gfunc.ts 24 KB

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