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;
}
Example #2
0
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;
}
Example #3
0
/*
 * 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);
}
Example #4
0
/*
 *
 * @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;
}
Example #5
0
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;
}
Example #6
0
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;
}
Example #8
0
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));
}
Example #9
0
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));

}
Example #10
0
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;
}