Branch: master
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
178 lines (153 sloc) 6.4 KB
\d .grafana
// user defined column name of time column
// user defined column name of sym column
// user defined date range to find syms from
// user defined number of ticks to return
// user defined query argument deliminator
// json types of kdb datatypes
// milliseconds between 1970 and 2000
// wrapper if user has custom .z.pp
.z.pp:{[f;x]$[(`$"X-Grafana-Org-Id")in key last x;zpp;f]x}[@[value;`.z.pp;{{[x]}}]];
// return alive response for GET requests{[f;x]
$[(`$"X-Grafana-Org-Id")in key last x;"HTTP/1.1 200 OK\r\nConnection: close\r\n\r\n";f x]
// retrieve and convert Grafana HTTP POST request then process as either timeseries or table
// get API url from request
// cuts at first whitespace char to avoid splitting function params
r:(0;n?" ")cut n:first x;
// convert grafana message to q
rqt:.j.k r 1;
$["query"~r 0;query[rqt];"search"~r 0;search rqt;`$"Annotation url nyi"]
// retrieve final query and append to table to log
rqtype:raze rqt[`targets]`type;
:.h.hy[`json]$[rqtype~"timeserie";tsfunc rqt;tbfunc rqt];
finddistinctsyms:{?[x;enlist(>;timecol;(-;.z.p;timebackdate));1b;{x!x}enlist sym]sym};
// prefixes string c to each string s, seperated by del
prefix:{[c;s] (c,del),/:s};
// build drop down case options from tables in port
symtabs:tabs where sym in'cols each tabs;
timetabs:tabs where timecol in'cols each tabs;
rsp:string tabs;
if[count timetabs;
rsp,:s1:prefix["t";string timetabs];
rsp,:s2:prefix["g";string timetabs];
// suffix names of number columns to graph and other panel options
rsp,:raze(s2,'del),/:'c1:string {cols[x] where`number=types (0!meta x)`t}each timetabs;
rsp,:raze(prefix["o";string timetabs],'del),/:'c1;
if[count symtabs;
// suffix distinct syms to timeseries table and other panel options
rsp,:raze(s1,'del),/:'c2:string each finddistinctsyms'[timetabs];
rsp,:raze(prefix["o";string timetabs],'del),/:'{x[0] cross del,'string finddistinctsyms x 1}each (enlist each c1),'timetabs;
:.h.hy[`json].j.j rsp;
diskvals:{c:(count[x]-ticks)+til ticks;get'[.Q.ind[x;c]]};
catchvals:{@[diskvals;x;{[x;y]memvals x}[x]]};
istype:{[targ;char] (char,del)~2#targ};
isfunc:istype[;"f"]; istab:istype[;"t"];
// builds body of table response in Json adaptor schema
tabresponse:{[colname;coltype;rqt] .j.j enlist`columns`rows`type!(flip`text`type!(colname;coltype);catchvals rqt;`table)};
// process a table request and return in JSON format
rqt: raze rqt[`targets]`target;
// if f.t.func, drop first 4 chars
rqt:0!value $[isfunc[rqt] & istab 2_rqt; 4_rqt;
isfunc rqt; 2_rqt;
istab rqt; [rqt: `$del vs rqt; if[2<count rqt; symname: rqt 2]; rqt 1];
// get column names and associated types to fit format
colname:cols rqt;
coltype:types (0!meta rqt)`t;
// search rqt for sym if symname was set
if[-11h=type symname; rqt:?[rqt;enlist(=;sym;enlist symname);0b;()]];
// process a timeseries request and return in Json format, takes in query and information dictionary
targ: raze x[`targets]`target;
/ split arguments
numargs:count args:$[isfunc targ;(0;1+targ?del)cut targ:2_targ;`$del vs targ];
tyargs:$[10h=abs type args 0;`$1#;]args 0;
// manipulate queried table
coln:cols rqt:0!value args 1;
// function to convert time to milliseconds, takes timestamp
mil:{floor epoch+(`long$x)%1000000};
// ensure time column is a timestamp
// get time range from grafana
// select desired time period only
// form milliseconds since epoch column
rqt:@[rqt;`msec;:;mil rqt timecol];
// cases for graph/table and sym arguments
$[(2<numargs)and`g~tyargs;graphsym[args 2;rqt];
(2<numargs)and`t~tyargs;tablesym[coln;rqt;args 2];
(3=numargs)and`o~tyargs;othernosym[args 2;rqt];
(2=numargs)and`o~tyargs;othernosym[coln except timecol;rqt];
`$"Wrong input"]
// build JSON response for graph & other panels with no sym seperation
buildnosym:{y,`target`datapoints!(z 0;value each ?[x;();0b;z!z])};
nosymresponse:{[rqt;colname] .j.j buildnosym[rqt]\[();colname]};
// timeserie request on non-specific panel w/ no preference on sym seperation
// return columns with json number type only
colname:coln cross`msec;
// timeserie request on graph panel w/ no preference on sym seperation
// return columns with json number type only
coln:-1_coln where`number=types (0!meta rqt)`t;
colname:coln cross`msec;
// timeserie request on table panel w/ no preference on sym seperation
coltype:types -1_(0!meta rqt)`t;
// timeserie request on non-specific panel w/ data for one sym returned
// specify what columns data to return, taken from drop down input
data:flip value flip?[rqt;enlist(=;sym;enlist args 3);0b;outcol!outcol];
:.j.j enlist `target`datapoints!(args 3;data);
// timeserie request on graph panel w/ data for each sym returned
// return columns with json number type only
syms:`$string ?[rqt;();1b;{x!x}enlist sym]sym;
// specify what columns data to return, taken from drop down input
build:{[outcol;rqt;x;y]data:flip value flip?[rqt;enlist(=;sym;enlist y);0b;outcol!outcol];x,`target`datapoints!(y;data)};
:.j.j build[outcol;rqt]\[();syms];
// timeserie request on table panel w/ single sym specified
coltype:types -1_(0!meta rqt)`t;
// select data for requested sym only
rqt:?[rqt;enlist(=;sym;enlist symname);0b;()];