gpointer threaded_feed(gpointer args) { LogQueue *q = args; char *msg_str = "<155>2006-02-11T10:34:56+01:00 bzorp syslog-ng[23323]: árvíztűrőtükörfúrógép"; gint msg_len = strlen(msg_str); gint i; LogPathOptions path_options = LOG_PATH_OPTIONS_INIT; LogMessage *msg, *tmpl; GTimeVal start, end; GSockAddr *sa; glong diff; iv_init(); /* emulate main loop for LogQueue */ main_loop_worker_thread_start(NULL); sa = g_sockaddr_inet_new("10.10.10.10", 1010); tmpl = log_msg_new(msg_str, msg_len, sa, &parse_options); g_sockaddr_unref(sa); g_get_current_time(&start); for (i = 0; i < MESSAGES_PER_FEEDER; i++) { msg = log_msg_clone_cow(tmpl, &path_options); log_msg_add_ack(msg, &path_options); msg->ack_func = test_ack; log_queue_push_tail(q, msg, &path_options); if ((i & 0xFF) == 0) main_loop_worker_invoke_batch_callbacks(); } main_loop_worker_invoke_batch_callbacks(); g_get_current_time(&end); diff = g_time_val_diff(&end, &start); g_static_mutex_lock(&tlock); sum_time += diff; g_static_mutex_unlock(&tlock); log_msg_unref(tmpl); iv_deinit(); main_loop_worker_thread_stop(); return NULL; }
static gpointer _threaded_feed(gpointer args) { LogQueue *q = args; gint i; LogPathOptions path_options = LOG_PATH_OPTIONS_INIT; LogMessage *msg, *tmpl; GTimeVal start, end; glong diff; iv_init(); /* emulate main loop for LogQueue */ main_loop_worker_thread_start(NULL); tmpl = log_msg_new_empty(); g_get_current_time(&start); for (i = 0; i < MESSAGES_PER_FEEDER; i++) { msg = log_msg_clone_cow(tmpl, &path_options); log_msg_add_ack(msg, &path_options); msg->ack_func = test_ack; log_queue_push_tail(q, msg, &path_options); if ((i & 0xFF) == 0) main_loop_worker_invoke_batch_callbacks(); } main_loop_worker_invoke_batch_callbacks(); g_get_current_time(&end); diff = g_time_val_diff(&end, &start); g_static_mutex_lock(&tlock); sum_time += diff; g_static_mutex_unlock(&tlock); log_msg_unref(tmpl); main_loop_worker_thread_stop(); iv_deinit(); return NULL; }
/* * This function can be called any time when pattern-db is not processing * messages, but we expect the correllation timer to move forward. It * doesn't need to be called absolutely regularly as it'll use the current * system time to determine how much time has passed since the last * invocation. See the timing comment at pattern_db_process() for more * information. */ void pattern_db_timer_tick(PatternDB *self) { GTimeVal now; glong diff; PDBProcessParams process_params_p = {0}; PDBProcessParams *process_params = &process_params_p; g_static_rw_lock_writer_lock(&self->lock); self->timer_process_params = process_params; cached_g_current_time(&now); diff = g_time_val_diff(&now, &self->last_tick); if (diff > 1e6) { glong diff_sec = (glong) (diff / 1e6); timer_wheel_set_time(self->timer_wheel, timer_wheel_get_time(self->timer_wheel) + diff_sec); msg_debug("Advancing patterndb current time because of timer tick", evt_tag_long("utc", timer_wheel_get_time(self->timer_wheel))); /* update last_tick, take the fraction of the seconds not calculated into this update into account */ self->last_tick = now; g_time_val_add(&self->last_tick, - (glong)(diff - diff_sec * 1e6)); } else if (diff < 0) { /* time moving backwards, this can only happen if the computer's time * is changed. We don't update patterndb's idea of the time now, wait * another tick instead to update that instead. */ self->last_tick = now; } self->timer_process_params = NULL; g_static_rw_lock_writer_unlock(&self->lock); _flush_emitted_messages(self, process_params); }
/* * * @batch_items: the number of items processed in a batch (e.g. the number of items the consumer is preferred to process at a single invocation) * @partial_batch: true is returned if some elements (but less than batch_items) are already buffered * @timeout: the number of milliseconds that the consumer needs to wait before we can possibly proceed */ gboolean log_queue_check_items(LogQueue *self, gint *timeout, LogQueuePushNotifyFunc parallel_push_notify, gpointer user_data, GDestroyNotify user_data_destroy) { gint64 num_elements; g_static_mutex_lock(&self->lock); /* drop reference to the previous callback/userdata */ if (self->parallel_push_data && self->parallel_push_data_destroy) self->parallel_push_data_destroy(self->parallel_push_data); num_elements = log_queue_get_length(self); if (num_elements == 0) { self->parallel_push_notify = parallel_push_notify; self->parallel_push_data = user_data; self->parallel_push_data_destroy = user_data_destroy; g_static_mutex_unlock(&self->lock); return FALSE; } /* consume the user_data reference as we won't use the callback */ if (user_data && user_data_destroy) user_data_destroy(user_data); self->parallel_push_notify = NULL; self->parallel_push_data = NULL; g_static_mutex_unlock(&self->lock); /* recalculate buckets, throttle is only running in the output thread, no need to lock it. */ if (self->throttle > 0) { gint64 diff; gint new_buckets; GTimeVal now; g_get_current_time(&now); /* throttling is enabled, calculate new buckets */ if (self->last_throttle_check.tv_sec != 0) { diff = g_time_val_diff(&now, &self->last_throttle_check); } else { diff = 0; self->last_throttle_check = now; } new_buckets = (self->throttle * diff) / G_USEC_PER_SEC; if (new_buckets) { /* if new_buckets is zero, we don't save the current time as * last_throttle_check. The reason is that new_buckets could be * rounded to zero when only a minimal interval passes between * poll iterations. */ self->throttle_buckets = MIN(self->throttle, self->throttle_buckets + new_buckets); self->last_throttle_check = now; } if (num_elements && self->throttle_buckets == 0) { if (timeout) { /* we are unable to send because of throttling, make sure that we * wake up when the rate limits lets us send at least 1 message */ *timeout = (1000 / self->throttle) + 1; msg_debug("Throttling output", evt_tag_int("wait", *timeout)); } return FALSE; } } return TRUE; }
gpointer Scheduler::jobThreadCallback(Scheduler * scheduler) { XOJ_CHECK_TYPE_OBJ(scheduler, Scheduler); while (scheduler->threadRunning) { // lock the whole scheduler g_mutex_lock(scheduler->schedulerMutex); g_mutex_lock(scheduler->blockRenderMutex); bool onlyNoneRenderJobs = false; glong diff = 1000; if (scheduler->blockRenderZoomTime) { GTimeVal time; g_get_current_time(&time); diff = g_time_val_diff(scheduler->blockRenderZoomTime, &time); if(diff <= 0) { g_free(scheduler->blockRenderZoomTime); scheduler->blockRenderZoomTime = NULL; } else { onlyNoneRenderJobs = true; } } g_mutex_unlock(scheduler->blockRenderMutex); g_mutex_lock(scheduler->jobQueueMutex); bool hasOnlyRenderJobs = false; Job * job = scheduler->getNextJobUnlocked(onlyNoneRenderJobs, &hasOnlyRenderJobs); if(job != NULL) { hasOnlyRenderJobs = false; } SDEBUG("get job: %ld\n", (long)job); if (!job) { // unlock the whole scheduler g_mutex_unlock(scheduler->schedulerMutex); if(hasOnlyRenderJobs) { if(scheduler->jobRenderThreadTimerId) { g_source_remove(scheduler->jobRenderThreadTimerId); } scheduler->jobRenderThreadTimerId = g_timeout_add(diff, (GSourceFunc)jobRenderThreadTimer, scheduler); } g_cond_wait(scheduler->jobQueueCond, scheduler->jobQueueMutex); g_mutex_unlock(scheduler->jobQueueMutex); continue; } SDEBUG("do job: %ld\n", (long)job); g_mutex_unlock(scheduler->jobQueueMutex); g_mutex_lock(scheduler->jobRunningMutex); job->execute(); job->unref(); g_mutex_unlock(scheduler->jobRunningMutex); // unlock the whole scheduler g_mutex_unlock(scheduler->schedulerMutex); SDEBUG("next\n", NULL); } SDEBUG("finished\n", NULL); return NULL; }
gboolean log_macro_expand(GString *result, gint id, gboolean escape, LogTemplateOptions *opts, gint tz, gint32 seq_num, const gchar *context_id, LogMessage *msg) { static LogTemplateOptions default_opts = { TRUE, TS_FMT_BSD, 0, { NULL, NULL }, { NULL, NULL } }; if (!opts) opts = &default_opts; switch (id) { case M_FACILITY: { /* facility */ const char *n; n = syslog_name_lookup_name_by_value(msg->pri & LOG_FACMASK, sl_facilities); if (n) { g_string_append(result, n); } else { format_uint32_padded(result, 0, 0, 16, (msg->pri & LOG_FACMASK) >> 3); } break; } case M_FACILITY_NUM: { format_uint32_padded(result, 0, 0, 10, (msg->pri & LOG_FACMASK) >> 3); break; } case M_LEVEL: { /* level */ const char *n; n = syslog_name_lookup_name_by_value(msg->pri & LOG_PRIMASK, sl_levels); if (n) { g_string_append(result, n); } else { format_uint32_padded(result, 0, 0, 10, msg->pri & LOG_PRIMASK); } break; } case M_LEVEL_NUM: { format_uint32_padded(result, 0, 0, 10, msg->pri & LOG_PRIMASK); break; } case M_TAG: { format_uint32_padded(result, 2, '0', 16, msg->pri); break; } case M_TAGS: { log_msg_print_tags(msg, result); break; } case M_BSDTAG: { format_uint32_padded(result, 0, 0, 10, (msg->pri & LOG_PRIMASK)); g_string_append_c(result, (((msg->pri & LOG_FACMASK) >> 3) + 'A')); break; } case M_PRI: { format_uint32_padded(result, 0, 0, 10, msg->pri); break; } case M_HOST: { if (msg->flags & LF_CHAINED_HOSTNAME) { /* host */ const gchar *p1, *p2; int remaining, length; gssize host_len; const gchar *host = log_msg_get_value(msg, LM_V_HOST, &host_len); p1 = memchr(host, '@', host_len); if (p1) p1++; else p1 = host; remaining = host_len - (p1 - host); p2 = memchr(p1, '/', remaining); length = p2 ? p2 - p1 : host_len - (p1 - host); result_append(result, p1, length, escape); } else { result_append_value(result, msg, LM_V_HOST, escape); } break; } case M_SDATA: if (escape) { GString *sdstr = g_string_sized_new(0); log_msg_append_format_sdata(msg, sdstr, seq_num); result_append(result, sdstr->str, sdstr->len, TRUE); g_string_free(sdstr, TRUE); } else { log_msg_append_format_sdata(msg, result, seq_num); } break; case M_MSGHDR: if ((msg->flags & LF_LEGACY_MSGHDR)) { /* fast path for now, as most messages come from legacy devices */ result_append_value(result, msg, LM_V_LEGACY_MSGHDR, escape); } else { /* message, complete with program name and pid */ gssize len; len = result->len; result_append_value(result, msg, LM_V_PROGRAM, escape); if (len != result->len) { const gchar *pid = log_msg_get_value(msg, LM_V_PID, &len); if (len > 0) { result_append(result, "[", 1, FALSE); result_append(result, pid, len, escape); result_append(result, "]", 1, FALSE); } result_append(result, ": ", 2, FALSE); } } break; case M_MESSAGE: if (cfg_is_config_version_older(configuration, 0x0300)) log_macro_expand(result, M_MSGHDR, escape, opts, tz, seq_num, context_id, msg); result_append_value(result, msg, LM_V_MESSAGE, escape); break; case M_SOURCE_IP: { gchar *ip; if (msg->saddr && (g_sockaddr_inet_check(msg->saddr) || #if ENABLE_IPV6 g_sockaddr_inet6_check(msg->saddr)) #else 0) #endif ) { gchar buf[MAX_SOCKADDR_STRING]; g_sockaddr_format(msg->saddr, buf, sizeof(buf), GSA_ADDRESS_ONLY); ip = buf; } else { ip = "127.0.0.1"; } result_append(result, ip, strlen(ip), escape); break; } case M_SEQNUM: { if (seq_num) { format_uint32_padded(result, 0, 0, 10, seq_num); } break; } case M_CONTEXT_ID: { if (context_id) { result_append(result, context_id, strlen(context_id), escape); } break; } case M_LOGHOST: { gsize hname_len; const gchar *hname = get_local_hostname(&hname_len); result_append(result, hname, hname_len, escape); break; } case M_SYSUPTIME: { GTimeVal ct; g_get_current_time(&ct); format_uint64_padded(result, 0, 0, 10, g_time_val_diff(&ct, &app_uptime) / 1000 / 10); break; } default: { /* year, month, day */ struct tm *tm, tm_storage; gchar buf[64]; gint length; time_t t; LogStamp *stamp, sstamp; glong zone_ofs; guint tmp_hour; if (id >= M_TIME_FIRST && id <= M_TIME_LAST) { stamp = &msg->timestamps[LM_TS_STAMP]; } else if (id >= M_TIME_FIRST + M_RECVD_OFS && id <= M_TIME_LAST + M_RECVD_OFS) { id -= M_RECVD_OFS; stamp = &msg->timestamps[LM_TS_RECVD]; } else if (id >= M_TIME_FIRST + M_STAMP_OFS && id <= M_TIME_LAST + M_STAMP_OFS) { id -= M_STAMP_OFS; stamp = &msg->timestamps[LM_TS_STAMP]; } else if (id >= M_TIME_FIRST + M_CSTAMP_OFS && id <= M_TIME_LAST + M_CSTAMP_OFS) { GTimeVal tv; id -= M_CSTAMP_OFS; cached_g_current_time(&tv); sstamp.tv_sec = tv.tv_sec; sstamp.tv_usec = tv.tv_usec; sstamp.zone_offset = -1; stamp = &sstamp; } else { g_assert_not_reached(); break; } /* try to use the following zone values in order: * destination specific timezone, if one is specified * message specific timezone, if one is specified * local timezone */ zone_ofs = (opts->time_zone_info[tz] != NULL ? time_zone_info_get_offset(opts->time_zone_info[tz], stamp->tv_sec) : stamp->zone_offset); if (zone_ofs == -1) zone_ofs = stamp->zone_offset; t = stamp->tv_sec + zone_ofs; cached_gmtime(&t, &tm_storage); tm = &tm_storage; switch (id) { case M_WEEK_DAY_ABBREV: g_string_append_len(result, weekday_names_abbrev[tm->tm_wday], 3); break; case M_WEEK_DAY_NAME: g_string_append(result, weekday_names[tm->tm_wday]); break; case M_WEEK_DAY: format_uint32_padded(result, 0, 0, 10, tm->tm_wday + 1); break; case M_WEEK: format_uint32_padded(result, 2, '0', 10, (tm->tm_yday - (tm->tm_wday - 1 + 7) % 7 + 7) / 7); break; case M_YEAR: format_uint32_padded(result, 4, '0', 10, tm->tm_year + 1900); break; case M_YEAR_DAY: format_uint32_padded(result, 3, '0', 10, tm->tm_yday + 1); break; case M_MONTH: format_uint32_padded(result, 2, '0', 10, tm->tm_mon + 1); break; case M_MONTH_WEEK: format_uint32_padded(result, 0, 0, 10, ((tm->tm_mday / 7) + ((tm->tm_wday > 0) && ((tm->tm_mday % 7) >= tm->tm_wday)))); break; case M_MONTH_ABBREV: g_string_append_len(result, month_names_abbrev[tm->tm_mon], 3); break; case M_MONTH_NAME: g_string_append(result, month_names[tm->tm_mon]); break; case M_DAY: format_uint32_padded(result, 2, '0', 10, tm->tm_mday); break; case M_HOUR: format_uint32_padded(result, 2, '0', 10, tm->tm_hour); break; case M_HOUR12: if (tm->tm_hour < 12) tmp_hour = tm->tm_hour; else tmp_hour = tm->tm_hour - 12; if (tmp_hour == 0) tmp_hour = 12; format_uint32_padded(result, 2, '0', 10, tmp_hour); break; case M_MIN: format_uint32_padded(result, 2, '0', 10, tm->tm_min); break; case M_SEC: format_uint32_padded(result, 2, '0', 10, tm->tm_sec); break; case M_MSEC: format_uint32_padded(result, 3, '0', 10, stamp->tv_usec/1000); break; case M_USEC: format_uint32_padded(result, 6, '0', 10, stamp->tv_usec); break; case M_AMPM: g_string_append(result, tm->tm_hour < 12 ? "AM" : "PM"); break; case M_DATE: case M_STAMP: case M_ISODATE: case M_FULLDATE: case M_UNIXTIME: { gint format = id == M_DATE ? TS_FMT_BSD : id == M_ISODATE ? TS_FMT_ISO : id == M_FULLDATE ? TS_FMT_FULL : id == M_UNIXTIME ? TS_FMT_UNIX : opts->ts_format; log_stamp_append_format(stamp, result, format, zone_ofs, opts->frac_digits); break; } case M_TZ: case M_TZOFFSET: length = format_zone_info(buf, sizeof(buf), zone_ofs); g_string_append_len(result, buf, length); break; } break; } }
static gboolean log_writer_fd_prepare(GSource *source, gint *timeout) { LogWriterWatch *self = (LogWriterWatch *) source; gint64 num_elements = log_queue_get_length(self->writer->queue); GTimeVal now; GIOCondition proto_cond; self->pollfd.events = G_IO_ERR; self->pollfd.revents = 0; g_source_get_current_time(source, &now); if (log_proto_prepare(self->proto, &self->pollfd.fd, &proto_cond, timeout)) return TRUE; /* recalculate buckets */ if (self->writer->options->throttle > 0) { gint64 diff; gint new_buckets; /* throttling is enabled, calculate new buckets */ if (self->last_throttle_check.tv_sec != 0) { diff = g_time_val_diff(&now, &self->last_throttle_check); } else { diff = 0; self->last_throttle_check = now; } new_buckets = (self->writer->options->throttle * diff) / G_USEC_PER_SEC; if (new_buckets) { /* if new_buckets is zero, we don't save the current time as * last_throttle_check. The reason is that new_buckets could be * rounded to zero when only a minimal interval passes between * poll iterations. */ self->writer->throttle_buckets = MIN(self->writer->options->throttle, self->writer->throttle_buckets + new_buckets); self->last_throttle_check = now; } } if (G_UNLIKELY(self->error_suspend)) { *timeout = g_time_val_diff(&self->error_suspend_target, &now) / 1000; if (*timeout <= 0) { msg_notice("Error suspend timeout has elapsed, attempting to write again", evt_tag_int("fd", log_proto_get_fd(self->proto)), NULL); self->error_suspend = FALSE; *timeout = -1; } else { return FALSE; } } if ((self->writer->options->flush_lines == 0 && (!log_writer_throttling(self->writer) && num_elements != 0)) || (self->writer->options->flush_lines > 0 && (!log_writer_throttling(self->writer) && num_elements >= self->writer->options->flush_lines))) { /* we need to flush our buffers */ self->pollfd.events |= proto_cond; } else if (num_elements && !log_writer_throttling(self->writer)) { /* our buffer does not contain enough elements to flush, but we do not * want to wait more than flush_timeout time */ if (!self->flush_waiting_for_timeout) { /* start waiting */ *timeout = self->writer->options->flush_timeout; g_source_get_current_time(source, &self->flush_target); g_time_val_add(&self->flush_target, *timeout * 1000); self->flush_waiting_for_timeout = TRUE; } else { glong to = g_time_val_diff(&self->flush_target, &now) / 1000; if (to <= 0) { /* timeout elapsed, start polling again */ if (self->writer->flags & LW_ALWAYS_WRITABLE) return TRUE; self->pollfd.events = proto_cond; } else { *timeout = to; } } return FALSE; } else { if (num_elements && log_writer_throttling(self->writer)) { /* we are unable to send because of throttling, make sure that we * wake up when the rate limits lets us send at least 1 message */ *timeout = (1000 / self->writer->options->throttle) + 1; msg_debug("Throttling output", evt_tag_int("wait", *timeout), NULL); } } if (self->writer->flags & LW_DETECT_EOF && (self->pollfd.events & G_IO_IN) == 0) { self->pollfd.events |= G_IO_HUP | G_IO_IN; self->input_means_connection_broken = TRUE; } else { self->input_means_connection_broken = FALSE; } self->flush_waiting_for_timeout = FALSE; if ((self->pollfd.events & G_IO_OUT) && (self->writer->flags & LW_ALWAYS_WRITABLE)) { self->pollfd.revents = G_IO_OUT; return TRUE; } return FALSE; }
static gboolean log_reader_fd_check(GSource *source) { LogReaderWatch *self = (LogReaderWatch *) source; if (!log_source_free_to_send(&self->reader->super)) return FALSE; if (self->reader->options->follow_freq > 0) { struct stat st, followed_st; off_t pos = -1; gint fd = log_proto_get_fd(self->reader->proto); /* FIXME: this is a _HUGE_ layering violation... */ if (fd >= 0) { pos = lseek(fd, 0, SEEK_CUR); if (pos == (off_t) -1) { msg_error("Error invoking seek on followed file", evt_tag_errno("error", errno), NULL); return FALSE; } if (fstat(fd, &st) < 0) { if (errno == ESTALE) { msg_trace("log_reader_fd_check file moved ESTALE", evt_tag_str("follow_filename",self->reader->follow_filename), NULL); log_pipe_notify(self->reader->control, &self->reader->super.super, NC_FILE_MOVED, self); return FALSE; } else { msg_error("Error invoking fstat() on followed file", evt_tag_errno("error", errno), NULL); return FALSE; } } msg_trace("log_reader_fd_check", evt_tag_int("pos", pos), evt_tag_int("size", st.st_size), NULL); if (pos < st.st_size) { return TRUE; } else if (pos == st.st_size) { log_pipe_notify(self->reader->control, &self->reader->super.super, NC_FILE_EOF, self); } else if (pos > st.st_size) { /* reopen the file */ log_pipe_notify(self->reader->control, &self->reader->super.super, NC_FILE_MOVED, self); } } if (self->reader->follow_filename && stat(self->reader->follow_filename, &followed_st) != -1) { if (fd < 0 || (st.st_ino != followed_st.st_ino && followed_st.st_size > 0)) { msg_trace("log_reader_fd_check file moved eof", evt_tag_int("pos", pos), evt_tag_int("size", followed_st.st_size), evt_tag_str("follow_filename",self->reader->follow_filename), NULL); /* file was moved and we are at EOF, follow the new file */ log_pipe_notify(self->reader->control, &self->reader->super.super, NC_FILE_MOVED, self); } } else if (self->reader->follow_filename) { GTimeVal now; g_source_get_current_time(source, &now); if (g_time_val_diff(&now, &self->last_follow_freq_check) > self->reader->options->follow_freq * 1000) { msg_verbose("Follow mode file still does not exist", evt_tag_str("filename", self->reader->follow_filename), NULL); self->last_follow_freq_check = now; } } return FALSE; } return !!(self->pollfd.revents & (G_IO_IN | G_IO_OUT | G_IO_ERR | G_IO_HUP)); }
static void iterate_pattern(LogParser *p, const gchar *input) { LogMessage *msg; GTimeVal start, end; gint i; msg = _construct_msg(input); g_get_current_time(&start); for (i = 0; i < 100000; i++) { log_parser_process(p, &msg, NULL, log_msg_get_value(msg, LM_V_MESSAGE, NULL), -1); } log_msg_unref(msg); g_get_current_time(&end); printf(" %-90.*s speed: %12.3f msg/sec\n", (int) strlen(input), input, i * 1e6 / g_time_val_diff(&end, &start)); }
gboolean log_macro_expand(GString *result, gint id, gboolean escape, const LogTemplateOptions *opts, gint tz, gint32 seq_num, const gchar *context_id, const LogMessage *msg) { switch (id) { case M_FACILITY: { /* facility */ const char *n; n = syslog_name_lookup_name_by_value(msg->pri & LOG_FACMASK, sl_facilities); if (n) { g_string_append(result, n); } else { format_uint32_padded(result, 0, 0, 16, (msg->pri & LOG_FACMASK) >> 3); } break; } case M_FACILITY_NUM: { format_uint32_padded(result, 0, 0, 10, (msg->pri & LOG_FACMASK) >> 3); break; } case M_LEVEL: { /* level */ const char *n; n = syslog_name_lookup_name_by_value(msg->pri & LOG_PRIMASK, sl_levels); if (n) { g_string_append(result, n); } else { format_uint32_padded(result, 0, 0, 10, msg->pri & LOG_PRIMASK); } break; } case M_LEVEL_NUM: { format_uint32_padded(result, 0, 0, 10, msg->pri & LOG_PRIMASK); break; } case M_TAG: { format_uint32_padded(result, 2, '0', 16, msg->pri); break; } case M_TAGS: { log_msg_print_tags(msg, result); break; } case M_BSDTAG: { format_uint32_padded(result, 0, 0, 10, (msg->pri & LOG_PRIMASK)); g_string_append_c(result, (((msg->pri & LOG_FACMASK) >> 3) + 'A')); break; } case M_PRI: { format_uint32_padded(result, 0, 0, 10, msg->pri); break; } case M_HOST: { if (msg->flags & LF_CHAINED_HOSTNAME) { /* host */ const gchar *p1, *p2; int remaining, length; gssize host_len; const gchar *host = log_msg_get_value(msg, LM_V_HOST, &host_len); p1 = memchr(host, '@', host_len); if (p1) p1++; else p1 = host; remaining = host_len - (p1 - host); p2 = memchr(p1, '/', remaining); length = p2 ? p2 - p1 : host_len - (p1 - host); result_append(result, p1, length, escape); } else { _result_append_value(result, msg, LM_V_HOST, escape); } break; } case M_SDATA: if (escape) { GString *sdstr = g_string_sized_new(0); log_msg_append_format_sdata(msg, sdstr, seq_num); result_append(result, sdstr->str, sdstr->len, TRUE); g_string_free(sdstr, TRUE); } else { log_msg_append_format_sdata(msg, result, seq_num); } break; case M_MSGHDR: { gssize len; const gchar *p; p = log_msg_get_value(msg, LM_V_LEGACY_MSGHDR, &len); if (len > 0) result_append(result, p, len, escape); else { /* message, complete with program name and pid */ len = result->len; _result_append_value(result, msg, LM_V_PROGRAM, escape); if (len != result->len) { const gchar *pid = log_msg_get_value(msg, LM_V_PID, &len); if (len > 0) { result_append(result, "[", 1, FALSE); result_append(result, pid, len, escape); result_append(result, "]", 1, FALSE); } result_append(result, ": ", 2, FALSE); } } break; } case M_MESSAGE: _result_append_value(result, msg, LM_V_MESSAGE, escape); break; case M_SOURCE_IP: { gchar *ip; gchar buf[MAX_SOCKADDR_STRING]; if (_is_message_source_an_ip_address(msg)) { g_sockaddr_format(msg->saddr, buf, sizeof(buf), GSA_ADDRESS_ONLY); ip = buf; } else { ip = "127.0.0.1"; } result_append(result, ip, strlen(ip), escape); break; } case M_SEQNUM: { if (seq_num) { format_uint32_padded(result, 0, 0, 10, seq_num); } break; } case M_CONTEXT_ID: { if (context_id) { result_append(result, context_id, strlen(context_id), escape); } break; } case M_RCPTID: { rcptid_append_formatted_id(result, msg->rcptid); break; } case M_RUNID: { run_id_append_formatted_id(result); break; } case M_HOSTID: { host_id_append_formatted_id(result, msg->host_id); break; } case M_UNIQID: { if (msg->rcptid) { host_id_append_formatted_id(result, msg->host_id); g_string_append(result, "@"); format_uint64_padded(result, 16, '0', 16, msg->rcptid); break; } break; } case M_LOGHOST: { const gchar *hname = get_local_hostname_fqdn(); result_append(result, hname, -1, escape); break; } case M_SYSUPTIME: { GTimeVal ct; g_get_current_time(&ct); format_uint64_padded(result, 0, 0, 10, g_time_val_diff(&ct, &app_uptime) / 1000 / 10); break; } default: { /* year, month, day */ gchar buf[64]; gint length; const UnixTime *stamp; UnixTime sstamp; guint tmp_hour; if (id >= M_TIME_FIRST && id <= M_TIME_LAST) { stamp = &msg->timestamps[LM_TS_STAMP]; } else if (id >= M_TIME_FIRST + M_RECVD_OFS && id <= M_TIME_LAST + M_RECVD_OFS) { id -= M_RECVD_OFS; stamp = &msg->timestamps[LM_TS_RECVD]; } else if (id >= M_TIME_FIRST + M_STAMP_OFS && id <= M_TIME_LAST + M_STAMP_OFS) { id -= M_STAMP_OFS; stamp = &msg->timestamps[LM_TS_STAMP]; } else if (id >= M_TIME_FIRST + M_CSTAMP_OFS && id <= M_TIME_LAST + M_CSTAMP_OFS) { id -= M_CSTAMP_OFS; unix_time_set_now(&sstamp); stamp = &sstamp; } else if (id >= M_TIME_FIRST + M_PROCESSED_OFS && id <= M_TIME_LAST + M_PROCESSED_OFS) { id -= M_PROCESSED_OFS; stamp = &msg->timestamps[LM_TS_PROCESSED]; if (!unix_time_is_set(stamp)) { unix_time_set_now(&sstamp); stamp = &sstamp; } } else { g_assert_not_reached(); break; } /* try to use the following zone values in order: * destination specific timezone, if one is specified * message specific timezone, if one is specified * local timezone */ WallClockTime wct; convert_unix_time_to_wall_clock_time_with_tz_override(stamp, &wct, time_zone_info_get_offset(opts->time_zone_info[tz], stamp->ut_sec)); switch (id) { case M_WEEK_DAY_ABBREV: g_string_append_len(result, weekday_names_abbrev[wct.wct_wday], 3); break; case M_WEEK_DAY_NAME: g_string_append(result, weekday_names[wct.wct_wday]); break; case M_WEEK_DAY: format_uint32_padded(result, 0, 0, 10, wct.wct_wday + 1); break; case M_WEEK: format_uint32_padded(result, 2, '0', 10, (wct.wct_yday - (wct.wct_wday - 1 + 7) % 7 + 7) / 7); break; case M_YEAR: format_uint32_padded(result, 4, '0', 10, wct.wct_year + 1900); break; case M_YEAR_DAY: format_uint32_padded(result, 3, '0', 10, wct.wct_yday + 1); break; case M_MONTH: format_uint32_padded(result, 2, '0', 10, wct.wct_mon + 1); break; case M_MONTH_WEEK: format_uint32_padded(result, 0, 0, 10, ((wct.wct_mday / 7) + ((wct.wct_wday > 0) && ((wct.wct_mday % 7) >= wct.wct_wday)))); break; case M_MONTH_ABBREV: g_string_append_len(result, month_names_abbrev[wct.wct_mon], 3); break; case M_MONTH_NAME: g_string_append(result, month_names[wct.wct_mon]); break; case M_DAY: format_uint32_padded(result, 2, '0', 10, wct.wct_mday); break; case M_HOUR: format_uint32_padded(result, 2, '0', 10, wct.wct_hour); break; case M_HOUR12: if (wct.wct_hour < 12) tmp_hour = wct.wct_hour; else tmp_hour = wct.wct_hour - 12; if (tmp_hour == 0) tmp_hour = 12; format_uint32_padded(result, 2, '0', 10, tmp_hour); break; case M_MIN: format_uint32_padded(result, 2, '0', 10, wct.wct_min); break; case M_SEC: format_uint32_padded(result, 2, '0', 10, wct.wct_sec); break; case M_MSEC: format_uint32_padded(result, 3, '0', 10, stamp->ut_usec/1000); break; case M_USEC: format_uint32_padded(result, 6, '0', 10, stamp->ut_usec); break; case M_AMPM: g_string_append(result, wct.wct_hour < 12 ? "AM" : "PM"); break; case M_DATE: append_format_wall_clock_time(&wct, result, TS_FMT_BSD, opts->frac_digits); break; case M_STAMP: if (opts->ts_format == TS_FMT_UNIX) append_format_unix_time(stamp, result, TS_FMT_UNIX, wct.wct_gmtoff, opts->frac_digits); else append_format_wall_clock_time(&wct, result, opts->ts_format, opts->frac_digits); break; case M_ISODATE: append_format_wall_clock_time(&wct, result, TS_FMT_ISO, opts->frac_digits); break; case M_FULLDATE: append_format_wall_clock_time(&wct, result, TS_FMT_FULL, opts->frac_digits); break; case M_UNIXTIME: append_format_unix_time(stamp, result, TS_FMT_UNIX, wct.wct_gmtoff, opts->frac_digits); break; case M_TZ: case M_TZOFFSET: length = format_zone_info(buf, sizeof(buf), wct.wct_gmtoff); g_string_append_len(result, buf, length); break; default: g_assert_not_reached(); break; } break; } } return TRUE; }