gfunc.ts 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191
  1. import _ from 'lodash';
  2. import { isVersionGtOrEq } from 'app/core/utils/version';
  3. import { InterpolateFunction } from '@grafana/ui';
  4. const index: any = {};
  5. export interface FuncDef {
  6. name: any;
  7. category?: string;
  8. params?: any;
  9. defaultParams?: any;
  10. shortName?: any;
  11. fake?: boolean;
  12. version?: string;
  13. description?: string;
  14. }
  15. function addFuncDef(funcDef: FuncDef) {
  16. funcDef.params = funcDef.params || [];
  17. funcDef.defaultParams = funcDef.defaultParams || [];
  18. index[funcDef.name] = funcDef;
  19. if (funcDef.shortName) {
  20. index[funcDef.shortName] = funcDef;
  21. }
  22. }
  23. const optionalSeriesRefArgs = [{ name: 'other', type: 'value_or_series', optional: true, multiple: true }];
  24. addFuncDef({
  25. name: 'scaleToSeconds',
  26. category: 'Transform',
  27. params: [{ name: 'seconds', type: 'int' }],
  28. defaultParams: [1],
  29. });
  30. addFuncDef({
  31. name: 'perSecond',
  32. category: 'Transform',
  33. params: [{ name: 'max value', type: 'int', optional: true }],
  34. defaultParams: [],
  35. });
  36. addFuncDef({
  37. name: 'holtWintersForecast',
  38. category: 'Calculate',
  39. });
  40. addFuncDef({
  41. name: 'holtWintersConfidenceBands',
  42. category: 'Calculate',
  43. params: [{ name: 'delta', type: 'int' }],
  44. defaultParams: [3],
  45. });
  46. addFuncDef({
  47. name: 'holtWintersAberration',
  48. category: 'Calculate',
  49. params: [{ name: 'delta', type: 'int' }],
  50. defaultParams: [3],
  51. });
  52. addFuncDef({
  53. name: 'nPercentile',
  54. category: 'Calculate',
  55. params: [{ name: 'Nth percentile', type: 'int' }],
  56. defaultParams: [95],
  57. });
  58. addFuncDef({
  59. name: 'diffSeries',
  60. params: optionalSeriesRefArgs,
  61. defaultParams: ['#A'],
  62. category: 'Combine',
  63. });
  64. addFuncDef({
  65. name: 'stddevSeries',
  66. params: optionalSeriesRefArgs,
  67. defaultParams: [''],
  68. category: 'Combine',
  69. });
  70. addFuncDef({
  71. name: 'divideSeries',
  72. params: optionalSeriesRefArgs,
  73. defaultParams: ['#A'],
  74. category: 'Combine',
  75. });
  76. addFuncDef({
  77. name: 'multiplySeries',
  78. params: optionalSeriesRefArgs,
  79. defaultParams: ['#A'],
  80. category: 'Combine',
  81. });
  82. addFuncDef({
  83. name: 'asPercent',
  84. params: optionalSeriesRefArgs,
  85. defaultParams: ['#A'],
  86. category: 'Combine',
  87. });
  88. addFuncDef({
  89. name: 'group',
  90. params: optionalSeriesRefArgs,
  91. defaultParams: ['#A', '#B'],
  92. category: 'Combine',
  93. });
  94. addFuncDef({
  95. name: 'sumSeries',
  96. shortName: 'sum',
  97. category: 'Combine',
  98. params: optionalSeriesRefArgs,
  99. defaultParams: [''],
  100. });
  101. addFuncDef({
  102. name: 'averageSeries',
  103. shortName: 'avg',
  104. category: 'Combine',
  105. params: optionalSeriesRefArgs,
  106. defaultParams: [''],
  107. });
  108. addFuncDef({
  109. name: 'rangeOfSeries',
  110. category: 'Combine',
  111. });
  112. addFuncDef({
  113. name: 'percentileOfSeries',
  114. category: 'Combine',
  115. params: [{ name: 'n', type: 'int' }, { name: 'interpolate', type: 'boolean', options: ['true', 'false'] }],
  116. defaultParams: [95, 'false'],
  117. });
  118. addFuncDef({
  119. name: 'sumSeriesWithWildcards',
  120. category: 'Combine',
  121. params: [{ name: 'node', type: 'int', multiple: true }],
  122. defaultParams: [3],
  123. });
  124. addFuncDef({
  125. name: 'maxSeries',
  126. shortName: 'max',
  127. category: 'Combine',
  128. });
  129. addFuncDef({
  130. name: 'minSeries',
  131. shortName: 'min',
  132. category: 'Combine',
  133. });
  134. addFuncDef({
  135. name: 'averageSeriesWithWildcards',
  136. category: 'Combine',
  137. params: [{ name: 'node', type: 'int', multiple: true }],
  138. defaultParams: [3],
  139. });
  140. addFuncDef({
  141. name: 'alias',
  142. category: 'Alias',
  143. params: [{ name: 'alias', type: 'string' }],
  144. defaultParams: ['alias'],
  145. });
  146. addFuncDef({
  147. name: 'aliasSub',
  148. category: 'Alias',
  149. params: [{ name: 'search', type: 'string' }, { name: 'replace', type: 'string' }],
  150. defaultParams: ['', '\\1'],
  151. });
  152. addFuncDef({
  153. name: 'consolidateBy',
  154. category: 'Special',
  155. params: [
  156. {
  157. name: 'function',
  158. type: 'string',
  159. options: ['sum', 'average', 'min', 'max'],
  160. },
  161. ],
  162. defaultParams: ['max'],
  163. });
  164. addFuncDef({
  165. name: 'cumulative',
  166. category: 'Special',
  167. params: [],
  168. defaultParams: [],
  169. });
  170. addFuncDef({
  171. name: 'groupByNode',
  172. category: 'Combine',
  173. params: [
  174. {
  175. name: 'node',
  176. type: 'int',
  177. options: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12],
  178. },
  179. {
  180. name: 'function',
  181. type: 'string',
  182. options: ['sum', 'avg', 'maxSeries'],
  183. },
  184. ],
  185. defaultParams: [3, 'sum'],
  186. });
  187. addFuncDef({
  188. name: 'aliasByNode',
  189. category: 'Alias',
  190. params: [
  191. {
  192. name: 'node',
  193. type: 'int',
  194. options: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12],
  195. multiple: true,
  196. },
  197. ],
  198. defaultParams: [3],
  199. });
  200. addFuncDef({
  201. name: 'substr',
  202. category: 'Special',
  203. params: [
  204. {
  205. name: 'start',
  206. type: 'int',
  207. options: [-6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12],
  208. },
  209. {
  210. name: 'stop',
  211. type: 'int',
  212. options: [-6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12],
  213. },
  214. ],
  215. defaultParams: [0, 0],
  216. });
  217. addFuncDef({
  218. name: 'sortByName',
  219. category: 'Sorting',
  220. params: [
  221. {
  222. name: 'natural',
  223. type: 'boolean',
  224. options: ['true', 'false'],
  225. optional: true,
  226. },
  227. ],
  228. defaultParams: ['false'],
  229. });
  230. addFuncDef({
  231. name: 'sortByMaxima',
  232. category: 'Sorting',
  233. });
  234. addFuncDef({
  235. name: 'sortByMinima',
  236. category: 'Sorting',
  237. });
  238. addFuncDef({
  239. name: 'sortByTotal',
  240. category: 'Sorting',
  241. });
  242. addFuncDef({
  243. name: 'aliasByMetric',
  244. category: 'Alias',
  245. });
  246. addFuncDef({
  247. name: 'randomWalk',
  248. fake: true,
  249. category: 'Special',
  250. params: [{ name: 'name', type: 'string' }],
  251. defaultParams: ['randomWalk'],
  252. });
  253. addFuncDef({
  254. name: 'countSeries',
  255. category: 'Combine',
  256. });
  257. addFuncDef({
  258. name: 'constantLine',
  259. category: 'Special',
  260. params: [{ name: 'value', type: 'int' }],
  261. defaultParams: [10],
  262. });
  263. addFuncDef({
  264. name: 'cactiStyle',
  265. category: 'Special',
  266. });
  267. addFuncDef({
  268. name: 'keepLastValue',
  269. category: 'Transform',
  270. params: [{ name: 'n', type: 'int' }],
  271. defaultParams: [100],
  272. });
  273. addFuncDef({
  274. name: 'changed',
  275. category: 'Special',
  276. params: [],
  277. defaultParams: [],
  278. });
  279. addFuncDef({
  280. name: 'scale',
  281. category: 'Transform',
  282. params: [{ name: 'factor', type: 'int' }],
  283. defaultParams: [1],
  284. });
  285. addFuncDef({
  286. name: 'offset',
  287. category: 'Transform',
  288. params: [{ name: 'amount', type: 'int' }],
  289. defaultParams: [10],
  290. });
  291. addFuncDef({
  292. name: 'transformNull',
  293. category: 'Transform',
  294. params: [{ name: 'amount', type: 'int' }],
  295. defaultParams: [0],
  296. });
  297. addFuncDef({
  298. name: 'integral',
  299. category: 'Transform',
  300. });
  301. addFuncDef({
  302. name: 'derivative',
  303. category: 'Transform',
  304. });
  305. addFuncDef({
  306. name: 'nonNegativeDerivative',
  307. category: 'Transform',
  308. params: [{ name: 'max value or 0', type: 'int', optional: true }],
  309. defaultParams: [''],
  310. });
  311. addFuncDef({
  312. name: 'timeShift',
  313. category: 'Transform',
  314. params: [
  315. {
  316. name: 'amount',
  317. type: 'select',
  318. options: ['1h', '6h', '12h', '1d', '2d', '7d', '14d', '30d'],
  319. },
  320. ],
  321. defaultParams: ['1d'],
  322. });
  323. addFuncDef({
  324. name: 'timeStack',
  325. category: 'Transform',
  326. params: [
  327. {
  328. name: 'timeShiftUnit',
  329. type: 'select',
  330. options: ['1h', '6h', '12h', '1d', '2d', '7d', '14d', '30d'],
  331. },
  332. { name: 'timeShiftStart', type: 'int' },
  333. { name: 'timeShiftEnd', type: 'int' },
  334. ],
  335. defaultParams: ['1d', 0, 7],
  336. });
  337. addFuncDef({
  338. name: 'summarize',
  339. category: 'Transform',
  340. params: [
  341. { name: 'interval', type: 'string' },
  342. {
  343. name: 'func',
  344. type: 'select',
  345. options: ['sum', 'avg', 'min', 'max', 'last'],
  346. },
  347. {
  348. name: 'alignToFrom',
  349. type: 'boolean',
  350. optional: true,
  351. options: ['false', 'true'],
  352. },
  353. ],
  354. defaultParams: ['1h', 'sum', 'false'],
  355. });
  356. addFuncDef({
  357. name: 'smartSummarize',
  358. category: 'Transform',
  359. params: [
  360. { name: 'interval', type: 'string' },
  361. {
  362. name: 'func',
  363. type: 'select',
  364. options: ['sum', 'avg', 'min', 'max', 'last'],
  365. },
  366. ],
  367. defaultParams: ['1h', 'sum'],
  368. });
  369. addFuncDef({
  370. name: 'absolute',
  371. category: 'Transform',
  372. });
  373. addFuncDef({
  374. name: 'hitcount',
  375. category: 'Transform',
  376. params: [{ name: 'interval', type: 'string' }],
  377. defaultParams: ['10s'],
  378. });
  379. addFuncDef({
  380. name: 'log',
  381. category: 'Transform',
  382. params: [{ name: 'base', type: 'int' }],
  383. defaultParams: ['10'],
  384. });
  385. addFuncDef({
  386. name: 'averageAbove',
  387. category: 'Filter Series',
  388. params: [{ name: 'n', type: 'int' }],
  389. defaultParams: [25],
  390. });
  391. addFuncDef({
  392. name: 'averageBelow',
  393. category: 'Filter Series',
  394. params: [{ name: 'n', type: 'int' }],
  395. defaultParams: [25],
  396. });
  397. addFuncDef({
  398. name: 'currentAbove',
  399. category: 'Filter Series',
  400. params: [{ name: 'n', type: 'int' }],
  401. defaultParams: [25],
  402. });
  403. addFuncDef({
  404. name: 'currentBelow',
  405. category: 'Filter Series',
  406. params: [{ name: 'n', type: 'int' }],
  407. defaultParams: [25],
  408. });
  409. addFuncDef({
  410. name: 'maximumAbove',
  411. category: 'Filter Series',
  412. params: [{ name: 'value', type: 'int' }],
  413. defaultParams: [0],
  414. });
  415. addFuncDef({
  416. name: 'maximumBelow',
  417. category: 'Filter Series',
  418. params: [{ name: 'value', type: 'int' }],
  419. defaultParams: [0],
  420. });
  421. addFuncDef({
  422. name: 'minimumAbove',
  423. category: 'Filter Series',
  424. params: [{ name: 'value', type: 'int' }],
  425. defaultParams: [0],
  426. });
  427. addFuncDef({
  428. name: 'minimumBelow',
  429. category: 'Filter Series',
  430. params: [{ name: 'value', type: 'int' }],
  431. defaultParams: [0],
  432. });
  433. addFuncDef({
  434. name: 'limit',
  435. category: 'Filter Series',
  436. params: [{ name: 'n', type: 'int' }],
  437. defaultParams: [5],
  438. });
  439. addFuncDef({
  440. name: 'mostDeviant',
  441. category: 'Filter Series',
  442. params: [{ name: 'n', type: 'int' }],
  443. defaultParams: [10],
  444. });
  445. addFuncDef({
  446. name: 'exclude',
  447. category: 'Filter Series',
  448. params: [{ name: 'exclude', type: 'string' }],
  449. defaultParams: ['exclude'],
  450. });
  451. addFuncDef({
  452. name: 'highestCurrent',
  453. category: 'Filter Series',
  454. params: [{ name: 'count', type: 'int' }],
  455. defaultParams: [5],
  456. });
  457. addFuncDef({
  458. name: 'highestMax',
  459. category: 'Filter Series',
  460. params: [{ name: 'count', type: 'int' }],
  461. defaultParams: [5],
  462. });
  463. addFuncDef({
  464. name: 'lowestCurrent',
  465. category: 'Filter Series',
  466. params: [{ name: 'count', type: 'int' }],
  467. defaultParams: [5],
  468. });
  469. addFuncDef({
  470. name: 'movingAverage',
  471. category: 'Calculate',
  472. params: [
  473. {
  474. name: 'windowSize',
  475. type: 'int_or_interval',
  476. options: ['5', '7', '10', '5min', '10min', '30min', '1hour'],
  477. },
  478. ],
  479. defaultParams: [10],
  480. });
  481. addFuncDef({
  482. name: 'movingMedian',
  483. category: 'Calculate',
  484. params: [
  485. {
  486. name: 'windowSize',
  487. type: 'int_or_interval',
  488. options: ['5', '7', '10', '5min', '10min', '30min', '1hour'],
  489. },
  490. ],
  491. defaultParams: ['5'],
  492. });
  493. addFuncDef({
  494. name: 'stdev',
  495. category: 'Calculate',
  496. params: [{ name: 'n', type: 'int' }, { name: 'tolerance', type: 'int' }],
  497. defaultParams: [5, 0.1],
  498. });
  499. addFuncDef({
  500. name: 'highestAverage',
  501. category: 'Filter Series',
  502. params: [{ name: 'count', type: 'int' }],
  503. defaultParams: [5],
  504. });
  505. addFuncDef({
  506. name: 'lowestAverage',
  507. category: 'Filter Series',
  508. params: [{ name: 'count', type: 'int' }],
  509. defaultParams: [5],
  510. });
  511. addFuncDef({
  512. name: 'removeAbovePercentile',
  513. category: 'Filter Data',
  514. params: [{ name: 'n', type: 'int' }],
  515. defaultParams: [5],
  516. });
  517. addFuncDef({
  518. name: 'removeAboveValue',
  519. category: 'Filter Data',
  520. params: [{ name: 'n', type: 'int' }],
  521. defaultParams: [5],
  522. });
  523. addFuncDef({
  524. name: 'removeBelowPercentile',
  525. category: 'Filter Data',
  526. params: [{ name: 'n', type: 'int' }],
  527. defaultParams: [5],
  528. });
  529. addFuncDef({
  530. name: 'removeBelowValue',
  531. category: 'Filter Data',
  532. params: [{ name: 'n', type: 'int' }],
  533. defaultParams: [5],
  534. });
  535. addFuncDef({
  536. name: 'useSeriesAbove',
  537. category: 'Filter Series',
  538. params: [{ name: 'value', type: 'int' }, { name: 'search', type: 'string' }, { name: 'replace', type: 'string' }],
  539. defaultParams: [0, 'search', 'replace'],
  540. });
  541. ////////////////////
  542. // Graphite 1.0.x //
  543. ////////////////////
  544. addFuncDef({
  545. name: 'aggregateLine',
  546. category: 'Calculate',
  547. params: [
  548. {
  549. name: 'func',
  550. type: 'select',
  551. options: ['sum', 'avg', 'min', 'max', 'last'],
  552. },
  553. ],
  554. defaultParams: ['avg'],
  555. version: '1.0',
  556. });
  557. addFuncDef({
  558. name: 'averageOutsidePercentile',
  559. category: 'Filter Series',
  560. params: [{ name: 'n', type: 'int' }],
  561. defaultParams: [95],
  562. version: '1.0',
  563. });
  564. addFuncDef({
  565. name: 'delay',
  566. category: 'Transform',
  567. params: [{ name: 'steps', type: 'int' }],
  568. defaultParams: [1],
  569. version: '1.0',
  570. });
  571. addFuncDef({
  572. name: 'exponentialMovingAverage',
  573. category: 'Calculate',
  574. params: [
  575. {
  576. name: 'windowSize',
  577. type: 'int_or_interval',
  578. options: ['5', '7', '10', '5min', '10min', '30min', '1hour'],
  579. },
  580. ],
  581. defaultParams: [10],
  582. version: '1.0',
  583. });
  584. addFuncDef({
  585. name: 'fallbackSeries',
  586. category: 'Special',
  587. params: [{ name: 'fallback', type: 'string' }],
  588. defaultParams: ['constantLine(0)'],
  589. version: '1.0',
  590. });
  591. addFuncDef({
  592. name: 'grep',
  593. category: 'Filter Series',
  594. params: [{ name: 'grep', type: 'string' }],
  595. defaultParams: ['grep'],
  596. version: '1.0',
  597. });
  598. addFuncDef({
  599. name: 'groupByNodes',
  600. category: 'Combine',
  601. params: [
  602. {
  603. name: 'function',
  604. type: 'string',
  605. options: ['sum', 'avg', 'maxSeries'],
  606. },
  607. {
  608. name: 'node',
  609. type: 'int',
  610. options: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12],
  611. multiple: true,
  612. },
  613. ],
  614. defaultParams: ['sum', 3],
  615. version: '1.0',
  616. });
  617. addFuncDef({
  618. name: 'integralByInterval',
  619. category: 'Transform',
  620. params: [
  621. {
  622. name: 'intervalUnit',
  623. type: 'select',
  624. options: ['1h', '6h', '12h', '1d', '2d', '7d', '14d', '30d'],
  625. },
  626. ],
  627. defaultParams: ['1d'],
  628. version: '1.0',
  629. });
  630. addFuncDef({
  631. name: 'interpolate',
  632. category: 'Transform',
  633. params: [{ name: 'limit', type: 'int', optional: true }],
  634. defaultParams: [],
  635. version: '1.0',
  636. });
  637. addFuncDef({
  638. name: 'invert',
  639. category: 'Transform',
  640. version: '1.0',
  641. });
  642. addFuncDef({
  643. name: 'isNonNull',
  644. category: 'Combine',
  645. version: '1.0',
  646. });
  647. addFuncDef({
  648. name: 'linearRegression',
  649. category: 'Calculate',
  650. params: [
  651. {
  652. name: 'startSourceAt',
  653. type: 'select',
  654. options: ['-1h', '-6h', '-12h', '-1d', '-2d', '-7d', '-14d', '-30d'],
  655. optional: true,
  656. },
  657. {
  658. name: 'endSourceAt',
  659. type: 'select',
  660. options: ['-1h', '-6h', '-12h', '-1d', '-2d', '-7d', '-14d', '-30d'],
  661. optional: true,
  662. },
  663. ],
  664. defaultParams: [],
  665. version: '1.0',
  666. });
  667. addFuncDef({
  668. name: 'mapSeries',
  669. shortName: 'map',
  670. params: [{ name: 'node', type: 'int' }],
  671. defaultParams: [3],
  672. category: 'Combine',
  673. version: '1.0',
  674. });
  675. addFuncDef({
  676. name: 'movingMin',
  677. category: 'Calculate',
  678. params: [
  679. {
  680. name: 'windowSize',
  681. type: 'int_or_interval',
  682. options: ['5', '7', '10', '5min', '10min', '30min', '1hour'],
  683. },
  684. ],
  685. defaultParams: [10],
  686. version: '1.0',
  687. });
  688. addFuncDef({
  689. name: 'movingMax',
  690. category: 'Calculate',
  691. params: [
  692. {
  693. name: 'windowSize',
  694. type: 'int_or_interval',
  695. options: ['5', '7', '10', '5min', '10min', '30min', '1hour'],
  696. },
  697. ],
  698. defaultParams: [10],
  699. version: '1.0',
  700. });
  701. addFuncDef({
  702. name: 'movingSum',
  703. category: 'Calculate',
  704. params: [
  705. {
  706. name: 'windowSize',
  707. type: 'int_or_interval',
  708. options: ['5', '7', '10', '5min', '10min', '30min', '1hour'],
  709. },
  710. ],
  711. defaultParams: [10],
  712. version: '1.0',
  713. });
  714. addFuncDef({
  715. name: 'multiplySeriesWithWildcards',
  716. category: 'Combine',
  717. params: [
  718. {
  719. name: 'position',
  720. type: 'int',
  721. options: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12],
  722. multiple: true,
  723. },
  724. ],
  725. defaultParams: [2],
  726. version: '1.0',
  727. });
  728. addFuncDef({
  729. name: 'offsetToZero',
  730. category: 'Transform',
  731. version: '1.0',
  732. });
  733. addFuncDef({
  734. name: 'pow',
  735. category: 'Transform',
  736. params: [{ name: 'factor', type: 'int' }],
  737. defaultParams: [10],
  738. version: '1.0',
  739. });
  740. addFuncDef({
  741. name: 'powSeries',
  742. category: 'Transform',
  743. params: optionalSeriesRefArgs,
  744. defaultParams: [''],
  745. version: '1.0',
  746. });
  747. addFuncDef({
  748. name: 'reduceSeries',
  749. shortName: 'reduce',
  750. params: [
  751. {
  752. name: 'function',
  753. type: 'string',
  754. options: ['asPercent', 'diffSeries', 'divideSeries'],
  755. },
  756. {
  757. name: 'reduceNode',
  758. type: 'int',
  759. options: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13],
  760. },
  761. { name: 'reduceMatchers', type: 'string', multiple: true },
  762. ],
  763. defaultParams: ['asPercent', 2, 'used_bytes'],
  764. category: 'Combine',
  765. version: '1.0',
  766. });
  767. addFuncDef({
  768. name: 'removeBetweenPercentile',
  769. category: 'Filter Series',
  770. params: [{ name: 'n', type: 'int' }],
  771. defaultParams: [95],
  772. version: '1.0',
  773. });
  774. addFuncDef({
  775. name: 'removeEmptySeries',
  776. category: 'Filter Series',
  777. version: '1.0',
  778. });
  779. addFuncDef({
  780. name: 'squareRoot',
  781. category: 'Transform',
  782. version: '1.0',
  783. });
  784. addFuncDef({
  785. name: 'timeSlice',
  786. category: 'Transform',
  787. params: [
  788. {
  789. name: 'startSliceAt',
  790. type: 'select',
  791. options: ['-1h', '-6h', '-12h', '-1d', '-2d', '-7d', '-14d', '-30d'],
  792. },
  793. {
  794. name: 'endSliceAt',
  795. type: 'select',
  796. options: ['-1h', '-6h', '-12h', '-1d', '-2d', '-7d', '-14d', '-30d'],
  797. optional: true,
  798. },
  799. ],
  800. defaultParams: ['-1h'],
  801. version: '1.0',
  802. });
  803. addFuncDef({
  804. name: 'weightedAverage',
  805. category: 'Combine',
  806. params: [
  807. { name: 'other', type: 'value_or_series', optional: true },
  808. {
  809. name: 'node',
  810. type: 'int',
  811. options: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12],
  812. },
  813. ],
  814. defaultParams: ['#A', 4],
  815. version: '1.0',
  816. });
  817. addFuncDef({
  818. name: 'seriesByTag',
  819. category: 'Special',
  820. params: [{ name: 'tagExpression', type: 'string', multiple: true }],
  821. version: '1.1',
  822. });
  823. addFuncDef({
  824. name: 'groupByTags',
  825. category: 'Combine',
  826. params: [
  827. {
  828. name: 'function',
  829. type: 'string',
  830. options: ['sum', 'avg', 'maxSeries'],
  831. },
  832. { name: 'tag', type: 'string', multiple: true },
  833. ],
  834. defaultParams: ['sum', 'tag'],
  835. version: '1.1',
  836. });
  837. addFuncDef({
  838. name: 'aliasByTags',
  839. category: 'Alias',
  840. params: [{ name: 'tag', type: 'string', multiple: true }],
  841. defaultParams: ['tag'],
  842. version: '1.1',
  843. });
  844. function isVersionRelatedFunction(obj: { version: string }, graphiteVersion: string) {
  845. return !obj.version || isVersionGtOrEq(graphiteVersion, obj.version);
  846. }
  847. export class FuncInstance {
  848. def: any;
  849. params: any;
  850. text: any;
  851. added: boolean;
  852. constructor(funcDef: any, options: { withDefaultParams: any }) {
  853. this.def = funcDef;
  854. this.params = [];
  855. if (options && options.withDefaultParams) {
  856. this.params = funcDef.defaultParams.slice(0);
  857. }
  858. this.updateText();
  859. }
  860. render(metricExp: string, replaceVariables: InterpolateFunction): string {
  861. const str = this.def.name + '(';
  862. const parameters = _.map(this.params, (value, index) => {
  863. let paramType;
  864. if (index < this.def.params.length) {
  865. paramType = this.def.params[index].type;
  866. } else if (_.get(_.last(this.def.params), 'multiple')) {
  867. paramType = _.get(_.last(this.def.params), 'type');
  868. }
  869. // param types that should never be quoted
  870. if (_.includes(['value_or_series', 'boolean', 'int', 'float', 'node'], paramType)) {
  871. return value;
  872. }
  873. const valueInterpolated = _.isString(value) ? replaceVariables(value) : value;
  874. // param types that might be quoted
  875. // To quote variables correctly we need to interpolate it to check if it contains a numeric or string value
  876. if (_.includes(['int_or_interval', 'node_or_tag'], paramType) && _.isFinite(+valueInterpolated)) {
  877. return _.toString(value);
  878. }
  879. return "'" + value + "'";
  880. });
  881. // don't send any blank parameters to graphite
  882. while (parameters[parameters.length - 1] === '') {
  883. parameters.pop();
  884. }
  885. if (metricExp) {
  886. parameters.unshift(metricExp);
  887. }
  888. return str + parameters.join(', ') + ')';
  889. }
  890. _hasMultipleParamsInString(strValue: any, index: number) {
  891. if (strValue.indexOf(',') === -1) {
  892. return false;
  893. }
  894. if (this.def.params[index + 1] && this.def.params[index + 1].optional) {
  895. return true;
  896. }
  897. if (index + 1 >= this.def.params.length && _.get(_.last(this.def.params), 'multiple')) {
  898. return true;
  899. }
  900. return false;
  901. }
  902. updateParam(strValue: any, index: any) {
  903. // handle optional parameters
  904. // if string contains ',' and next param is optional, split and update both
  905. if (this._hasMultipleParamsInString(strValue, index)) {
  906. _.each(strValue.split(','), (partVal, idx) => {
  907. this.updateParam(partVal.trim(), index + idx);
  908. });
  909. return;
  910. }
  911. if (strValue === '' && (index >= this.def.params.length || this.def.params[index].optional)) {
  912. this.params.splice(index, 1);
  913. } else {
  914. this.params[index] = strValue;
  915. }
  916. this.updateText();
  917. }
  918. updateText() {
  919. if (this.params.length === 0) {
  920. this.text = this.def.name + '()';
  921. return;
  922. }
  923. let text = this.def.name + '(';
  924. text += this.params.join(', ');
  925. text += ')';
  926. this.text = text;
  927. }
  928. }
  929. function createFuncInstance(funcDef: any, options?: { withDefaultParams: any }, idx?: any) {
  930. if (_.isString(funcDef)) {
  931. funcDef = getFuncDef(funcDef, idx);
  932. }
  933. return new FuncInstance(funcDef, options);
  934. }
  935. function getFuncDef(name: string, idx?: any) {
  936. if (!(idx || index)[name]) {
  937. throw { message: 'Method not found ' + name };
  938. }
  939. return (idx || index)[name];
  940. }
  941. function getFuncDefs(graphiteVersion: string, idx?: any) {
  942. const funcs: any = {};
  943. _.forEach(idx || index, funcDef => {
  944. if (isVersionRelatedFunction(funcDef, graphiteVersion)) {
  945. funcs[funcDef.name] = _.assign({}, funcDef, {
  946. params: _.filter(funcDef.params, param => {
  947. return isVersionRelatedFunction(param, graphiteVersion);
  948. }),
  949. });
  950. }
  951. });
  952. return funcs;
  953. }
  954. // parse response from graphite /functions endpoint into internal format
  955. function parseFuncDefs(rawDefs: any) {
  956. const funcDefs: any = {};
  957. _.forEach(rawDefs || {}, (funcDef, funcName) => {
  958. // skip graphite graph functions
  959. if (funcDef.group === 'Graph') {
  960. return;
  961. }
  962. let description = funcDef.description;
  963. if (description) {
  964. // tidy up some pydoc syntax that rst2html can't handle
  965. description = description
  966. .replace(/:py:func:`(.+)( <[^>]*>)?`/g, '``$1``')
  967. .replace(/.. seealso:: /g, 'See also: ')
  968. .replace(/.. code-block *:: *none/g, '.. code-block::');
  969. }
  970. const func: FuncDef = {
  971. name: funcDef.name,
  972. description,
  973. category: funcDef.group,
  974. params: [],
  975. defaultParams: [],
  976. fake: false,
  977. };
  978. // get rid of the first "seriesList" param
  979. if (/^seriesLists?$/.test(_.get(funcDef, 'params[0].type', ''))) {
  980. // handle functions that accept multiple seriesLists
  981. // we leave the param in place but mark it optional, so users can add more series if they wish
  982. if (funcDef.params[0].multiple) {
  983. funcDef.params[0].required = false;
  984. // otherwise chop off the first param, it'll be handled separately
  985. } else {
  986. funcDef.params.shift();
  987. }
  988. // tag function as fake
  989. } else {
  990. func.fake = true;
  991. }
  992. _.forEach(funcDef.params, rawParam => {
  993. const param: any = {
  994. name: rawParam.name,
  995. type: 'string',
  996. optional: !rawParam.required,
  997. multiple: !!rawParam.multiple,
  998. options: undefined,
  999. };
  1000. if (rawParam.default !== undefined) {
  1001. func.defaultParams.push(_.toString(rawParam.default));
  1002. } else if (rawParam.suggestions) {
  1003. func.defaultParams.push(_.toString(rawParam.suggestions[0]));
  1004. } else {
  1005. func.defaultParams.push('');
  1006. }
  1007. if (rawParam.type === 'boolean') {
  1008. param.type = 'boolean';
  1009. param.options = ['true', 'false'];
  1010. } else if (rawParam.type === 'integer') {
  1011. param.type = 'int';
  1012. } else if (rawParam.type === 'float') {
  1013. param.type = 'float';
  1014. } else if (rawParam.type === 'node') {
  1015. param.type = 'node';
  1016. param.options = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'];
  1017. } else if (rawParam.type === 'nodeOrTag') {
  1018. param.type = 'node_or_tag';
  1019. param.options = ['name', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'];
  1020. } else if (rawParam.type === 'intOrInterval') {
  1021. param.type = 'int_or_interval';
  1022. } else if (rawParam.type === 'seriesList') {
  1023. param.type = 'value_or_series';
  1024. }
  1025. if (rawParam.options) {
  1026. param.options = _.map(rawParam.options, _.toString);
  1027. } else if (rawParam.suggestions) {
  1028. param.options = _.map(rawParam.suggestions, _.toString);
  1029. }
  1030. func.params.push(param);
  1031. });
  1032. funcDefs[funcName] = func;
  1033. });
  1034. return funcDefs;
  1035. }
  1036. export default {
  1037. createFuncInstance: createFuncInstance,
  1038. getFuncDef: getFuncDef,
  1039. getFuncDefs: getFuncDefs,
  1040. parseFuncDefs: parseFuncDefs,
  1041. };