void log_reader_set_options(LogReader *s, LogPipe *control, LogReaderOptions *options, const gchar *stats_id, const gchar *stats_instance) { LogReader *self = (LogReader *) s; /* log_reader_reopen() needs to be called prior to set_options. This is * an ugly hack, but at least it is more explicitly than what used to be * here, which silently ignored if self->proto was NULL. */ g_assert(self->proto != NULL); gboolean pos_tracked = log_proto_server_is_position_tracked(self->proto); log_source_set_options(&self->super, &options->super, stats_id, stats_instance, (options->flags & LR_THREADED), pos_tracked, control->expr_node); log_pipe_unref(self->control); log_pipe_ref(control); self->control = control; self->options = options; log_proto_server_set_options(self->proto, &self->options->proto_options.super); log_proto_server_set_ack_tracker(self->proto, self->super.ack_tracker); }
static void early_ack_tracker_track_msg(AckTracker *s, LogMessage *msg) { EarlyAckTracker *self = (EarlyAckTracker *)s; log_pipe_ref((LogPipe *)self->super.source); msg->ack_record = (AckRecord *)(&self->ack_record_storage); }
static gboolean afprogram_dd_reopen(AFProgramDestDriver *self) { int fd; if (self->pid != -1) { msg_verbose("Sending destination program a TERM signal", evt_tag_str("cmdline", self->cmdline->str), evt_tag_int("child_pid", self->pid), NULL); kill(self->pid, SIGTERM); self->pid = -1; } msg_verbose("Starting destination program", evt_tag_str("cmdline", self->cmdline->str), NULL); if (!afprogram_popen(self->cmdline->str, G_IO_OUT, &self->pid, &fd)) return FALSE; child_manager_register(self->pid, afprogram_dd_exit, log_pipe_ref(&self->super.super.super), (GDestroyNotify) log_pipe_unref); g_fd_set_nonblock(fd, TRUE); log_writer_reopen(self->writer, log_proto_text_client_new(log_transport_plain_new(fd, 0))); return TRUE; }
/* * Update the suppress timer in a deferred manner, possibly batching the * results of multiple updates to the suppress timer. This is necessary as * suppress timer updates must run in the main thread, and updating it every * time a new message comes in would cause enormous latency in the fast * path. By collecting multiple updates * * msec == 0 means to turn off the suppress timer * msec > 0 to enable the timer with the specified timeout * * NOTE: suppress_lock must be held. */ static void log_writer_update_suppress_timer(LogWriter *self, glong sec) { gboolean invoke; struct timespec next_expires; iv_validate_now(); /* we deliberately use nsec == 0 in order to increase the likelyhood that * we target the same second, in case only a fraction of a second has * passed between two updates. */ if (sec) { next_expires.tv_nsec = 0; next_expires.tv_sec = iv_now.tv_sec + sec; } else { next_expires.tv_sec = 0; next_expires.tv_nsec = 0; } /* last update was finished, we need to invoke the updater again */ invoke = ((next_expires.tv_sec != self->suppress_timer_expires.tv_sec) || (next_expires.tv_nsec != self->suppress_timer_expires.tv_nsec)) && self->suppress_timer_updated; self->suppress_timer_updated = FALSE; if (invoke) { self->suppress_timer_expires = next_expires; g_static_mutex_unlock(&self->suppress_lock); log_pipe_ref(&self->super); main_loop_call((void *(*)(void *)) log_writer_perform_suppress_timer_update, self, FALSE); g_static_mutex_lock(&self->suppress_lock); } }
void log_driver_append(LogDriver *self, LogDriver *next) { if (self->drv_next) log_pipe_unref(&self->drv_next->super); self->drv_next = (LogDriver *) log_pipe_ref(&next->super); }
static void log_writer_io_flush_output(gpointer s) { LogWriter *self = (LogWriter *) s; main_loop_assert_main_thread(); log_writer_stop_watches(self); log_pipe_ref(&self->super); if ((self->options->options & LWO_THREADED)) { main_loop_io_worker_job_submit(&self->io_job); } else { /* Checking main_loop_io_worker_job_quit() helps to speed up the * reload process. If reload/shutdown is requested we shouldn't do * anything here, a final flush will be attempted in * log_writer_deinit(). * * Our current understanding is that it doesn't prevent race * conditions of any kind. */ if (!main_loop_io_worker_job_quit()) { log_writer_work_perform(s); log_writer_work_finished(s); } } }
static void log_reader_io_process_input(gpointer s) { LogReader *self = (LogReader *) s; log_reader_stop_watches(self); log_pipe_ref(&self->super.super); if ((self->options->flags & LR_THREADED)) { main_loop_io_worker_job_submit(&self->io_job); } else { /* Checking main_loop_io_worker_job_quit() helps to speed up the * reload process. If reload/shutdown is requested we shouldn't do * anything here, outstanding messages will be processed by the new * configuration. * * Our current understanding is that it doesn't prevent race * conditions of any kind. */ if (!main_loop_io_worker_job_quit()) { log_reader_work_perform(s); log_reader_work_finished(s); } } }
gboolean afsocket_dd_start_connect(AFSocketDestDriver *self) { int sock, rc; gchar buf1[MAX_SOCKADDR_STRING], buf2[MAX_SOCKADDR_STRING]; if (!afsocket_open_socket(self->bind_addr, !!(self->flags & AFSOCKET_STREAM), &sock)) { return FALSE; } if (self->setup_socket && !self->setup_socket(self, sock)) { close(sock); return FALSE; } rc = g_connect(sock, self->dest_addr); if (rc == G_IO_STATUS_NORMAL) { self->fd = sock; afsocket_dd_connected(self); } else if (rc == G_IO_STATUS_ERROR && errno == EINPROGRESS) { GSource *source; /* we must wait until connect succeeds */ self->fd = sock; source = g_connect_source_new(sock); /* a reference is added on behalf of the source, it will be unrefed when * the source is destroyed */ log_pipe_ref(&self->super.super); g_source_set_callback(source, (GSourceFunc) afsocket_dd_connected, self, (GDestroyNotify) log_pipe_unref); self->source_id = g_source_attach(source, NULL); g_source_unref(source); } else { /* error establishing connection */ msg_error("Connection failed", evt_tag_int("fd", sock), evt_tag_str("server", g_sockaddr_format(self->dest_addr, buf2, sizeof(buf2), GSA_FULL)), evt_tag_str("local", g_sockaddr_format(self->bind_addr, buf1, sizeof(buf1), GSA_FULL)), evt_tag_errno(EVT_TAG_OSERROR, errno), NULL); close(sock); return FALSE; } return TRUE; }
static LogReaderWatch * log_reader_watch_new(LogReader *reader, LogProto *proto) { LogReaderWatch *self = (LogReaderWatch *) g_source_new(&log_reader_source_funcs, sizeof(LogReaderWatch)); log_pipe_ref(&reader->super.super); self->reader = reader; self->proto = proto; g_source_set_priority(&self->super, LOG_PRIORITY_READER); g_source_add_poll(&self->super, &self->pollfd); return self; }
static gboolean afprogram_sd_init(LogPipe *s) { AFProgramSourceDriver *self = (AFProgramSourceDriver *) s; GlobalConfig *cfg = log_pipe_get_config(s); gint fd; if (!log_src_driver_init_method(s)) return FALSE; if (cfg) log_reader_options_init(&self->reader_options, cfg, self->super.super.group); msg_verbose("Starting source program", evt_tag_str("cmdline", self->process_info.cmdline->str)); if (!afprogram_popen(&self->process_info, G_IO_IN, &fd)) return FALSE; /* parent */ child_manager_register(self->process_info.pid, afprogram_sd_exit, log_pipe_ref(&self->super.super.super), (GDestroyNotify) log_pipe_unref); g_fd_set_nonblock(fd, TRUE); g_fd_set_cloexec(fd, TRUE); if (!self->reader) { LogTransport *transport; transport = log_transport_pipe_new(fd); self->reader = log_reader_new(s->cfg); log_reader_reopen(self->reader, log_proto_text_server_new(transport, &self->reader_options.proto_options.super), poll_fd_events_new(fd)); log_reader_set_options(self->reader, s, &self->reader_options, STATS_LEVEL0, SCS_PROGRAM, self->super.super.id, self->process_info.cmdline->str); } log_pipe_append((LogPipe *) self->reader, &self->super.super.super); if (!log_pipe_init((LogPipe *) self->reader)) { msg_error("Error initializing program source, closing fd", evt_tag_int("fd", fd)); log_pipe_unref((LogPipe *) self->reader); self->reader = NULL; close(fd); return FALSE; } return TRUE; }
void journal_reader_set_options(LogPipe *s, LogPipe *control, JournalReaderOptions *options, gint stats_level, gint stats_source, const gchar *stats_id, const gchar *stats_instance) { JournalReader *self = (JournalReader *) s; log_source_set_options(&self->super, &options->super, stats_level, stats_source, stats_id, stats_instance, (options->flags & JR_THREADED), TRUE, control->expr_node); log_pipe_unref(self->control); log_pipe_ref(control); self->control = control; self->options = options; }
static void afsocket_sc_set_owner(AFSocketSourceConnection *self, AFSocketSourceDriver *owner) { if (self->owner) { log_pipe_unref(&self->owner->super.super.super); } self->owner = owner; log_pipe_ref(&owner->super.super.super); log_pipe_append(&self->super, &owner->super.super.super); }
void log_reader_set_options(LogPipe *s, LogPipe *control, LogReaderOptions *options, gint stats_level, gint stats_source, const gchar *stats_id, const gchar *stats_instance) { LogReader *self = (LogReader *) s; log_source_set_options(&self->super, &options->super, stats_level, stats_source, stats_id, stats_instance, (options->flags & LR_THREADED)); log_pipe_unref(self->control); log_pipe_ref(control); self->control = control; self->options = options; }
static GSource * log_writer_watch_new(LogWriter *writer, LogProto *proto) { LogWriterWatch *self = (LogWriterWatch *) g_source_new(&log_writer_source_funcs, sizeof(LogWriterWatch)); self->writer = writer; self->proto = proto; log_pipe_ref(&self->writer->super); g_source_set_priority(&self->super, LOG_PRIORITY_WRITER); if ((writer->flags & LW_ALWAYS_WRITABLE) == 0) g_source_add_poll(&self->super, &self->pollfd); return &self->super; }
static gboolean afprogram_dd_restore_reload_store_item(AFProgramDestDriver *self, GlobalConfig *cfg) { AFProgramReloadStoreItem *restored_info = (AFProgramReloadStoreItem *)cfg_persist_config_fetch(cfg, afprogram_dd_format_persist_name(self)); if (restored_info) { self->pid = restored_info->pid; self->writer = restored_info->writer; child_manager_register(self->pid, afprogram_dd_exit, log_pipe_ref(&self->super.super.super), (GDestroyNotify)log_pipe_unref); g_free(restored_info); } return !!(self->writer); }
AFSocketSourceConnection * afsocket_sc_new(AFSocketSourceDriver *owner, GSockAddr *peer_addr, int fd) { AFSocketSourceConnection *self = g_new0(AFSocketSourceConnection, 1); log_pipe_init_instance(&self->super); self->super.init = afsocket_sc_init; self->super.deinit = afsocket_sc_deinit; self->super.notify = afsocket_sc_notify; self->super.free_fn = afsocket_sc_free; log_pipe_ref(&owner->super.super.super); self->owner = owner; self->peer_addr = g_sockaddr_ref(peer_addr); self->sock = fd; return self; }
void log_reader_set_options(LogReader *s, LogPipe *control, LogReaderOptions *options, gint stats_level, gint stats_source, const gchar *stats_id, const gchar *stats_instance) { LogReader *self = (LogReader *) s; gboolean pos_tracked = ((self->proto != NULL) && log_proto_server_is_position_tracked(self->proto)); log_source_set_options(&self->super, &options->super, stats_level, stats_source, stats_id, stats_instance, (options->flags & LR_THREADED), pos_tracked, control->expr_node); log_pipe_unref(self->control); log_pipe_ref(control); self->control = control; self->options = options; if (self->proto) log_proto_server_set_options(self->proto, &self->options->proto_options.super); }
static void afsocket_sc_set_owner(AFSocketSourceConnection *self, AFSocketSourceDriver *owner) { GlobalConfig *cfg = log_pipe_get_config(&owner->super.super.super); if (self->owner) log_pipe_unref(&self->owner->super.super.super); log_pipe_ref(&owner->super.super.super); self->owner = owner; self->super.expr_node = owner->super.super.super.expr_node; log_pipe_set_config(&self->super, cfg); if (self->reader) log_pipe_set_config((LogPipe *) self->reader, cfg); log_pipe_append(&self->super, &owner->super.super.super); }
static gboolean afprogram_dd_reopen(AFProgramDestDriver *self) { int fd; afprogram_dd_kill_child(self); msg_verbose("Starting destination program", evt_tag_str("cmdline", self->cmdline->str), NULL); if (!afprogram_popen(self->cmdline->str, G_IO_OUT, &self->pid, &fd)) return FALSE; child_manager_register(self->pid, afprogram_dd_exit, log_pipe_ref(&self->super.super.super), (GDestroyNotify) log_pipe_unref); g_fd_set_nonblock(fd, TRUE); log_writer_reopen(self->writer, log_proto_text_client_new(log_transport_pipe_new(fd), &self->writer_options.proto_options.super)); return TRUE; }
static inline gboolean afprogram_dd_open_program(AFProgramDestDriver *self, int *fd) { if (self->process_info.pid == -1) { msg_verbose("Starting destination program", evt_tag_str("cmdline", self->process_info.cmdline->str)); if (!afprogram_popen(&self->process_info, G_IO_OUT, fd)) return FALSE; g_fd_set_nonblock(*fd, TRUE); } child_manager_register(self->process_info.pid, afprogram_dd_exit, log_pipe_ref(&self->super.super.super), (GDestroyNotify)log_pipe_unref); return TRUE; }
PollEvents * poll_file_changes_new(gint fd, const gchar *follow_filename, gint follow_freq, LogPipe *control) { PollFileChanges *self = g_new0(PollFileChanges, 1); self->super.stop_watches = poll_file_changes_stop_watches; self->super.update_watches = poll_file_changes_update_watches; self->super.free_fn = poll_file_changes_free; self->fd = fd; self->follow_filename = g_strdup(follow_filename); self->follow_freq = follow_freq; self->control = log_pipe_ref(control); IV_TIMER_INIT(&self->follow_timer); self->follow_timer.cookie = self; self->follow_timer.handler = poll_file_changes_check_file; return &self->super; }
static void _io_process_input(gpointer s) { JournalReader *self = (JournalReader *) s; _stop_watches(self); log_pipe_ref(&self->super.super); if ((self->options->flags & JR_THREADED)) { main_loop_io_worker_job_submit(&self->io_job); } else { if (!main_loop_worker_job_quit()) { _work_perform(s); _work_finished(s); } } }
static void late_ack_tracker_track_msg(AckTracker *s, LogMessage *msg) { LateAckTracker *self = (LateAckTracker *)s; LogSource *source = self->super.source; g_assert(self->pending_ack_record != NULL); log_pipe_ref((LogPipe *)source); msg->ack_record = (AckRecord *)self->pending_ack_record; _late_tracker_lock(self); { LateAckRecord *ack_rec; ack_rec = (LateAckRecord *)ring_buffer_push(&self->ack_record_storage); g_assert(ack_rec == self->pending_ack_record); } _late_tracker_unlock(self); self->pending_ack_record = NULL; }
static void _remove_file_reader(FileReader *reader, gpointer user_data) { WildcardSourceDriver *self = (WildcardSourceDriver *) user_data; _deleted_cb(reader, user_data); log_pipe_ref(&reader->super); if (g_hash_table_remove(self->file_readers, reader->filename->str)) { msg_debug("File is removed from the file list", evt_tag_str("Filename", reader->filename->str)); } else { msg_error("Can't remove the file reader", evt_tag_str("Filename", reader->filename->str)); } log_pipe_unref(&reader->super); gchar *full_path = pending_file_list_pop(self->waiting_list); if (full_path) { _create_file_reader(self, full_path); g_free(full_path); } }
gboolean afsocket_sd_init(LogPipe *s) { AFSocketSourceDriver *self = (AFSocketSourceDriver *) s; gint sock; gboolean res = FALSE; GlobalConfig *cfg = log_pipe_get_config(s); #if ENABLE_SSL if (self->flags & AFSOCKET_REQUIRE_TLS && !self->tls_context) { msg_error("Transport TLS was specified, but TLS related parameters missing", NULL); return FALSE; } #endif if (!self->bind_addr) { msg_error("No bind address set;", NULL); } log_reader_options_init(&self->reader_options, cfg, self->super.group); /* fetch persistent connections first */ if ((self->flags & AFSOCKET_KEEP_ALIVE)) { GList *p; self->connections = cfg_persist_config_fetch(cfg, afsocket_sd_format_persist_name(self, FALSE), NULL, NULL); for (p = self->connections; p; p = p->next) { afsocket_sc_set_owner((AFSocketSourceConnection *) p->data, self); } } /* ok, we have connection list, check if we need to open a listener */ sock = -1; if (self->flags & AFSOCKET_STREAM) { GSource *source; if (self->flags & AFSOCKET_KEEP_ALIVE) { /* NOTE: this assumes that fd 0 will never be used for listening fds, * main.c opens fd 0 so this assumption can hold */ sock = GPOINTER_TO_UINT(cfg_persist_config_fetch(cfg, afsocket_sd_format_persist_name(self, TRUE), NULL, NULL)) - 1; } if (sock == -1) { if (!afsocket_open_socket(self->bind_addr, !!(self->flags & AFSOCKET_STREAM), &sock)) return self->super.optional; } /* set up listening source */ if (listen(sock, self->listen_backlog) < 0) { msg_error("Error during listen()", evt_tag_errno(EVT_TAG_OSERROR, errno), NULL); close(sock); return FALSE; } if (self->setup_socket && !self->setup_socket(self, sock)) { close(sock); return FALSE; } self->fd = sock; source = g_listen_source_new(self->fd); /* the listen_source references us, which is freed when the source is deleted */ log_pipe_ref(s); g_source_set_callback(source, afsocket_sd_accept, self, (GDestroyNotify) log_pipe_unref); self->source_id = g_source_attach(source, NULL); g_source_unref(source); res = TRUE; } else { if (!self->connections) { if (!afsocket_open_socket(self->bind_addr, !!(self->flags & AFSOCKET_STREAM), &sock)) return self->super.optional; } self->fd = -1; if (!self->setup_socket(self, sock)) { close(sock); return FALSE; } /* we either have self->connections != NULL, or sock contains a new fd */ if (self->connections || afsocket_sd_process_connection(self, NULL, self->bind_addr, sock)) res = TRUE; } return res; }
static gboolean afprogram_dd_init(LogPipe *s, GlobalConfig *cfg, PersistentConfig *persist) { AFProgramDestDriver *self = (AFProgramDestDriver *) s; int msg_pipe[2]; if (cfg) log_writer_options_init(&self->writer_options, cfg, 0, afprogram_dd_format_stats_name(self)); msg_verbose("Starting destination program", evt_tag_str("cmdline", self->cmdline->str), NULL); if (pipe(msg_pipe) == -1) { msg_error("Error creating program pipe", evt_tag_str("cmdline", self->cmdline->str), evt_tag_errno(EVT_TAG_OSERROR, errno), NULL); return FALSE; } if ((self->pid = fork()) < 0) { msg_error("Error in fork()", evt_tag_errno(EVT_TAG_OSERROR, errno), NULL); close(msg_pipe[0]); close(msg_pipe[1]); return FALSE; } if (self->pid == 0) { /* child */ int devnull = open("/dev/null", O_WRONLY); if (devnull == -1) { _exit(127); } dup2(msg_pipe[0], 0); dup2(devnull, 1); dup2(devnull, 2); close(devnull); close(msg_pipe[0]); close(msg_pipe[1]); execl("/bin/sh", "/bin/sh", "-c", self->cmdline->str, NULL); _exit(127); } else { /* parent */ child_manager_register(self->pid, afprogram_dd_exit, log_pipe_ref(&self->super.super), (GDestroyNotify) log_pipe_unref); close(msg_pipe[0]); g_fd_set_nonblock(msg_pipe[1], TRUE); if (!self->writer) self->writer = log_writer_new(LW_FORMAT_FILE, s, &self->writer_options); #if 0/*start dongshu*/ log_writer_reopen(self->writer, fd_write_new(msg_pipe[1])); #else log_writer_reopen(self->writer, fd_write_new(msg_pipe[1],NULL)); #endif/*end*/ log_pipe_init(self->writer, NULL, NULL); log_pipe_append(&self->super.super, self->writer); } return TRUE; }