Exemple #1
0
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);
}
Exemple #3
0
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;
}
Exemple #4
0
/*
 * 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);
    }

}
Exemple #5
0
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);
}
Exemple #6
0
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);
        }
    }
}
Exemple #7
0
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);
        }
    }
}
Exemple #8
0
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;
}
Exemple #9
0
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;
}
Exemple #10
0
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;
}
Exemple #11
0
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;
}
Exemple #12
0
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);
}
Exemple #13
0
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;
}
Exemple #15
0
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);
}
Exemple #16
0
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;
}
Exemple #17
0
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);
}
Exemple #18
0
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);
}
Exemple #19
0
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;
}
Exemple #20
0
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;
}
Exemple #21
0
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;
}
Exemple #22
0
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);
        }
    }
}
Exemple #23
0
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;
}
Exemple #24
0
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);
    }
}
Exemple #25
0
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;
}
Exemple #26
0
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;
}