gfunc.ts 24 KB

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