guint id;
struct rspamd_config *cfg;
gdouble reload_time;
+ gdouble last_profile;
gint peak_cb;
};
enum rspamd_cache_savepoint_stage pass;
guint version;
guint items_inflight;
+ gboolean profile;
+ gdouble profile_start;
struct rspamd_metric_result *rs;
gdouble lim;
struct ev_loop *event_loop;
};
+/* At least once per minute */
+#define PROFILE_MAX_TIME (60.0)
+/* For messages larger than 2Mb enable profiling */
+#define PROFILE_MESSAGE_SIZE_THRESHOLD (1024 * 1024 * 2)
+/* Enable profile at least once per this amount of messages processed */
+#define PROFILE_PROBABILITY (0.01)
+
/* weight, frequency, time */
#define TIME_ALPHA (1.0)
#define WEIGHT_ALPHA (0.1)
elt = ucl_object_lookup (cur, "frequency");
if (elt && ucl_object_type (elt) == UCL_OBJECT) {
- const ucl_object_t *cur;
+ const ucl_object_t *freq_elt;
- cur = ucl_object_lookup (elt, "avg");
+ freq_elt = ucl_object_lookup (elt, "avg");
- if (cur) {
- item->st->avg_frequency = ucl_object_todouble (cur);
+ if (freq_elt) {
+ item->st->avg_frequency = ucl_object_todouble (freq_elt);
}
- cur = ucl_object_lookup (elt, "stddev");
+ freq_elt = ucl_object_lookup (elt, "stddev");
- if (cur) {
- item->st->stddev_frequency = ucl_object_todouble (cur);
+ if (freq_elt) {
+ item->st->stddev_frequency = ucl_object_todouble (freq_elt);
}
}
struct rspamd_symcache_item *item,
struct cache_savepoint *checkpoint)
{
- double t1 = 0;
struct rspamd_task **ptask;
lua_State *L;
gboolean check = TRUE;
if (check) {
msg_debug_cache_task ("execute %s, %d", item->symbol, item->id);
- t1 = ev_now (task->event_loop);
- dyn_item->start_msec = (t1 - task->time_virtual) * 1e3;
+
+ if (checkpoint->profile) {
+ dyn_item->start_msec = (rspamd_get_virtual_ticks () -
+ checkpoint->profile_start) * 1e3;
+ }
+
dyn_item->async_events = 0;
checkpoint->cur_item = item;
checkpoint->items_inflight ++;
rspamd_mempool_add_destructor (task->task_pool,
rspamd_symcache_order_unref, checkpoint->order);
+ /* Calculate profile probability */
+ ev_tstamp now = ev_now (task->event_loop);
+
+ if ((cache->last_profile == 0.0 || now > cache->last_profile + PROFILE_MAX_TIME) ||
+ (task->msg.len >= PROFILE_MESSAGE_SIZE_THRESHOLD) ||
+ (rspamd_random_double_fast () >= (1 - PROFILE_PROBABILITY))) {
+ msg_debug_cache_task ("enable profiling of symbols for task");
+ checkpoint->profile = TRUE;
+ checkpoint->profile_start = rspamd_get_virtual_ticks ();
+ cache->last_profile = now;
+ }
+
checkpoint->pass = RSPAMD_CACHE_PASS_INIT;
task->checkpoint = checkpoint;
struct cache_savepoint *checkpoint = task->checkpoint;
struct cache_dependency *rdep;
struct rspamd_symcache_dynamic_item *dyn_item;
- gdouble t2, diff;
+ gdouble diff;
guint i;
const gdouble slow_diff_limit = 300;
checkpoint->items_inflight --;
checkpoint->cur_item = NULL;
- t2 = ev_now (task->event_loop);
- diff = ((t2 - task->time_virtual) * 1e3 - dyn_item->start_msec);
-
- if (G_UNLIKELY (RSPAMD_TASK_IS_PROFILING (task))) {
- rspamd_task_profile_set (task, item->symbol, diff);
- }
+ if (checkpoint->profile) {
+ diff = ((rspamd_get_virtual_ticks () - checkpoint->profile_start) * 1e3 -
+ dyn_item->start_msec);
+ if (diff > slow_diff_limit) {
+ msg_info_task ("slow rule: %s(%d): %.2f ms", item->symbol, item->id,
+ diff);
+ }
- if (diff > slow_diff_limit) {
- msg_info_task ("slow rule: %s(%d): %.2f ms", item->symbol, item->id,
- diff);
- }
+ if (G_UNLIKELY (RSPAMD_TASK_IS_PROFILING (task))) {
+ rspamd_task_profile_set (task, item->symbol, diff);
+ }
- if (rspamd_worker_is_scanner (task->worker)) {
- rspamd_set_counter (item->cd, diff);
+ if (rspamd_worker_is_scanner (task->worker)) {
+ rspamd_set_counter (item->cd, diff);
+ }
}
/* Process all reverse dependencies */