You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

rrd.h 9.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. /*-
  2. * Copyright 2016 Vsevolod Stakhov
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #ifndef RRD_H_
  17. #define RRD_H_
  18. #include "config.h"
  19. /**
  20. * This file contains basic structure and functions to operate with round-robin databases
  21. */
  22. #define RRD_COOKIE "RRD"
  23. #define RRD_VERSION "0003"
  24. #define RRD_FLOAT_COOKIE ((double)8.642135E130)
  25. typedef union {
  26. unsigned long lv;
  27. double dv;
  28. } rrd_value_t;
  29. struct rrd_file_head {
  30. /* Data Base Identification Section ** */
  31. gchar cookie[4]; /* RRD */
  32. gchar version[5]; /* version of the format */
  33. gdouble float_cookie; /* is it the correct double representation ? */
  34. /* Data Base Structure Definition **** */
  35. gulong ds_cnt; /* how many different ds provid input to the rrd */
  36. gulong rra_cnt; /* how many rras will be maintained in the rrd */
  37. gulong pdp_step; /* pdp interval in seconds */
  38. rrd_value_t par[10]; /* global parameters ... unused
  39. at the moment */
  40. };
  41. enum rrd_dst_type {
  42. RRD_DST_INVALID = -1,
  43. RRD_DST_COUNTER = 0, /* data source types available */
  44. RRD_DST_ABSOLUTE,
  45. RRD_DST_GAUGE,
  46. RRD_DST_DERIVE,
  47. RRD_DST_CDEF
  48. };
  49. enum rrd_ds_param {
  50. RRD_DS_mrhb_cnt = 0, /* minimum required heartbeat */
  51. RRD_DS_min_val, /* the processed input of a ds must */
  52. RRD_DS_max_val, /* be between max_val and min_val
  53. * both can be set to UNKNOWN if you
  54. * do not care. Data outside the limits
  55. * set to UNKNOWN */
  56. RRD_DS_cdef = RRD_DS_mrhb_cnt
  57. }; /* pointer to encoded rpn expression only applies to DST_CDEF */
  58. /* The magic number here is one less than DS_NAM_SIZE */
  59. #define RRD_DS_NAM_SIZE 20
  60. #define RRD_DST_SIZE 20
  61. struct rrd_ds_def {
  62. gchar ds_nam[RRD_DS_NAM_SIZE]; /* Name of the data source (null terminated) */
  63. gchar dst[RRD_DST_SIZE]; /* Type of data source (null terminated) */
  64. rrd_value_t par[10]; /* index of this array see ds_param_en */
  65. };
  66. /* RRA definition */
  67. enum rrd_cf_type {
  68. RRD_CF_INVALID = -1,
  69. RRD_CF_AVERAGE = 0, /* data consolidation functions */
  70. RRD_CF_MINIMUM,
  71. RRD_CF_MAXIMUM,
  72. RRD_CF_LAST,
  73. };
  74. #define MAX_RRA_PAR_EN 10
  75. enum rrd_rra_param {
  76. RRA_cdp_xff_val = 0, /* what part of the consolidated
  77. * datapoint must be known, to produce a
  78. * valid entry in the rra */
  79. };
  80. #define RRD_CF_NAM_SIZE 20
  81. struct rrd_rra_def {
  82. gchar cf_nam[RRD_CF_NAM_SIZE]; /* consolidation function (null term) */
  83. gulong row_cnt; /* number of entries in the store */
  84. gulong pdp_cnt; /* how many primary data points are
  85. * required for a consolidated data point?*/
  86. rrd_value_t par[MAX_RRA_PAR_EN]; /* index see rra_param_en */
  87. };
  88. struct rrd_live_head {
  89. time_t last_up; /* when was rrd last updated */
  90. glong last_up_usec; /* micro seconds part of the update timestamp. Always >= 0 */
  91. };
  92. #define RRD_LAST_DS_LEN 30
  93. enum rrd_pdp_param {
  94. PDP_unkn_sec_cnt = 0, /* how many seconds of the current
  95. * pdp value is unknown data? */
  96. PDP_val
  97. }; /* current value of the pdp.
  98. this depends on dst */
  99. struct rrd_pdp_prep {
  100. gchar last_ds[RRD_LAST_DS_LEN]; /* the last reading from the data
  101. * source. this is stored in ASCII
  102. * to cater for very large counters
  103. * we might encounter in connection
  104. * with SNMP. */
  105. rrd_value_t scratch[10]; /* contents according to pdp_par_en */
  106. };
  107. #define RRD_MAX_CDP_PAR_EN 10
  108. #define RRD_MAX_CDP_FAILURES_IDX 8
  109. /* max CDP scratch entries avail to record violations for a FAILURES RRA */
  110. #define RRD_MAX_FAILURES_WINDOW_LEN 28
  111. enum rrd_cdp_param {
  112. CDP_val = 0,
  113. /* the base_interval is always an
  114. * average */
  115. CDP_unkn_pdp_cnt,
  116. /* how many unknown pdp were
  117. * integrated. This and the cdp_xff
  118. * will decide if this is going to
  119. * be a UNKNOWN or a valid value */
  120. CDP_hw_intercept,
  121. /* Current intercept coefficient for the Holt-Winters
  122. * prediction algorithm. */
  123. CDP_hw_last_intercept,
  124. /* Last iteration intercept coefficient for the Holt-Winters
  125. * prediction algorihtm. */
  126. CDP_hw_slope,
  127. /* Current slope coefficient for the Holt-Winters
  128. * prediction algorithm. */
  129. CDP_hw_last_slope,
  130. /* Last iteration slope coeffient. */
  131. CDP_null_count,
  132. /* Number of sequential Unknown (DNAN) values + 1 preceding
  133. * the current prediction.
  134. * */
  135. CDP_last_null_count,
  136. /* Last iteration count of Unknown (DNAN) values. */
  137. CDP_primary_val = 8,
  138. /* optimization for bulk updates: the value of the first CDP
  139. * value to be written in the bulk update. */
  140. CDP_secondary_val = 9,
  141. /* optimization for bulk updates: the value of subsequent
  142. * CDP values to be written in the bulk update. */
  143. CDP_hw_seasonal = CDP_hw_intercept,
  144. /* Current seasonal coefficient for the Holt-Winters
  145. * prediction algorithm. This is stored in CDP prep to avoid
  146. * redundant seek operations. */
  147. CDP_hw_last_seasonal = CDP_hw_last_intercept,
  148. /* Last iteration seasonal coefficient. */
  149. CDP_seasonal_deviation = CDP_hw_intercept,
  150. CDP_last_seasonal_deviation = CDP_hw_last_intercept,
  151. CDP_init_seasonal = CDP_null_count
  152. };
  153. struct rrd_cdp_prep {
  154. rrd_value_t scratch[RRD_MAX_CDP_PAR_EN];
  155. /* contents according to cdp_par_en *
  156. * init state should be NAN */
  157. };
  158. struct rrd_rra_ptr {
  159. gulong cur_row; /* current row in the rra */
  160. };
  161. /* Final rrd file structure */
  162. struct rspamd_rrd_file {
  163. struct rrd_file_head *stat_head; /* the static header */
  164. struct rrd_ds_def *ds_def; /* list of data source definitions */
  165. struct rrd_rra_def *rra_def; /* list of round robin archive def */
  166. struct rrd_live_head *live_head; /* rrd v >= 3 last_up with us */
  167. struct rrd_pdp_prep *pdp_prep; /* pdp data prep area */
  168. struct rrd_cdp_prep *cdp_prep; /* cdp prep area */
  169. struct rrd_rra_ptr *rra_ptr; /* list of rra pointers */
  170. gdouble *rrd_value; /* list of rrd values */
  171. gchar *filename;
  172. guint8 * map; /* mmapped area */
  173. gsize size; /* its size */
  174. gboolean finalized;
  175. gchar *id;
  176. gint fd;
  177. };
  178. /* Public API */
  179. /**
  180. * Open (and mmap) existing RRD file
  181. * @param filename path
  182. * @param err error pointer
  183. * @return rrd file structure
  184. */
  185. struct rspamd_rrd_file * rspamd_rrd_open (const gchar *filename, GError **err);
  186. /**
  187. * Create basic header for rrd file
  188. * @param filename file path
  189. * @param ds_count number of data sources
  190. * @param rra_count number of round robin archives
  191. * @param pdp_step step of primary data points
  192. * @param err error pointer
  193. * @return TRUE if file has been created
  194. */
  195. struct rspamd_rrd_file *rspamd_rrd_create (const gchar *filename,
  196. gulong ds_count,
  197. gulong rra_count,
  198. gulong pdp_step,
  199. gdouble initial_ticks,
  200. GError **err);
  201. /**
  202. * Add data sources to rrd file
  203. * @param filename path to file
  204. * @param ds array of struct rrd_ds_def
  205. * @param err error pointer
  206. * @return TRUE if data sources were added
  207. */
  208. gboolean rspamd_rrd_add_ds (struct rspamd_rrd_file * file,
  209. GArray *ds,
  210. GError **err);
  211. /**
  212. * Add round robin archives to rrd file
  213. * @param filename path to file
  214. * @param ds array of struct rrd_rra_def
  215. * @param err error pointer
  216. * @return TRUE if archives were added
  217. */
  218. gboolean rspamd_rrd_add_rra (struct rspamd_rrd_file *file,
  219. GArray *rra,
  220. GError **err);
  221. /**
  222. * Finalize rrd file header and initialize all RRA in the file
  223. * @param filename file path
  224. * @param err error pointer
  225. * @return TRUE if rrd file is ready for use
  226. */
  227. gboolean rspamd_rrd_finalize (struct rspamd_rrd_file *file, GError **err);
  228. /**
  229. * Add record to rrd file
  230. * @param file rrd file object
  231. * @param points points (must be row suitable for this RRA, depending on ds count)
  232. * @param err error pointer
  233. * @return TRUE if a row has been added
  234. */
  235. gboolean rspamd_rrd_add_record (struct rspamd_rrd_file *file,
  236. GArray *points,
  237. gdouble ticks,
  238. GError **err);
  239. /**
  240. * Close rrd file
  241. * @param file
  242. * @return
  243. */
  244. gint rspamd_rrd_close (struct rspamd_rrd_file * file);
  245. /*
  246. * Conversion functions
  247. */
  248. /**
  249. * Convert rrd dst type from string to numeric value
  250. */
  251. enum rrd_dst_type rrd_dst_from_string (const gchar *str);
  252. /**
  253. * Convert numeric presentation of dst to string
  254. */
  255. const gchar * rrd_dst_to_string (enum rrd_dst_type type);
  256. /**
  257. * Convert rrd consolidation function type from string to numeric value
  258. */
  259. enum rrd_cf_type rrd_cf_from_string (const gchar *str);
  260. /**
  261. * Convert numeric presentation of cf to string
  262. */
  263. const gchar * rrd_cf_to_string (enum rrd_cf_type type);
  264. /* Default RRA and DS */
  265. /**
  266. * Create default RRA
  267. */
  268. void rrd_make_default_rra (const gchar *cf_name,
  269. gulong pdp_cnt,
  270. gulong rows,
  271. struct rrd_rra_def *rra);
  272. /**
  273. * Create default DS
  274. */
  275. void rrd_make_default_ds (const gchar *name,
  276. const gchar *type,
  277. gulong pdp_step,
  278. struct rrd_ds_def *ds);
  279. /**
  280. * Open or create the default rspamd rrd file
  281. */
  282. struct rspamd_rrd_file *rspamd_rrd_file_default (const gchar *path,
  283. GError **err);
  284. /**
  285. * Returned by querying rrd database
  286. */
  287. struct rspamd_rrd_query_result {
  288. gulong rra_rows;
  289. gulong pdp_per_cdp;
  290. gulong ds_count;
  291. gdouble last_update;
  292. gulong cur_row;
  293. const gdouble *data;
  294. };
  295. /**
  296. * Return RRA data
  297. * @param file rrd file
  298. * @param rra_num number of rra to return data for
  299. * @return query result structure, that should be freed (using g_slice_free1) after usage
  300. */
  301. struct rspamd_rrd_query_result * rspamd_rrd_query (struct rspamd_rrd_file *file,
  302. gulong rra_num);
  303. #endif /* RRD_H_ */