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.

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