~ubuntu-branches/ubuntu/trusty/syslog-ng/trusty-proposed

« back to all changes in this revision

Viewing changes to src/messages.c

  • Committer: Bazaar Package Importer
  • Author(s): Laszlo Boszormenyi (GCS)
  • Date: 2010-03-14 12:57:49 UTC
  • mfrom: (1.3.1 upstream) (12.1.1 experimental)
  • Revision ID: james.westby@ubuntu.com-20100314125749-m3ats648sp2urg0f
Tags: 3.0.5-1
New upstream release, new maintainer.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * Copyright (c) 2002-2007 BalaBit IT Ltd, Budapest, Hungary                    
 
2
 * Copyright (c) 2002-2009 BalaBit IT Ltd, Budapest, Hungary
3
3
 *
4
4
 * This program is free software; you can redistribute it and/or modify it
5
5
 * under the terms of the GNU General Public License version 2 as published
20
20
 * along with this program; if not, write to the Free Software
21
21
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22
22
 */
23
 
 
 
23
  
24
24
#include "messages.h"
25
25
#include "logmsg.h"
26
26
 
33
33
 
34
34
#include <evtlog.h>
35
35
 
 
36
typedef struct _MsgContext
 
37
{
 
38
  guint16 recurse_count;
 
39
  gboolean recurse_warning:1;
 
40
} MsgContext;
36
41
 
37
42
gboolean debug_flag = 0;
38
43
gboolean verbose_flag = 0;
39
 
static gboolean log_stderr = FALSE, syslog_started = FALSE;
 
44
gboolean trace_flag = 0;
 
45
static gboolean log_stderr = FALSE;
 
46
static gboolean log_syslog = FALSE;
 
47
static gboolean syslog_started = FALSE;
40
48
static EVTCONTEXT *evt_context;
41
 
GQueue *internal_msg_queue = NULL;
 
49
MsgQueue *internal_msg_queue = NULL;
 
50
static GStaticPrivate msg_context_private = G_STATIC_PRIVATE_INIT;
 
51
static GStaticMutex evtlog_lock = G_STATIC_MUTEX_INIT;
 
52
 
 
53
 
 
54
static MsgContext *
 
55
msg_get_context(void)
 
56
{
 
57
  MsgContext *context;
 
58
 
 
59
  context = g_static_private_get(&msg_context_private);
 
60
  if (!context)
 
61
    {
 
62
      context = g_new0(MsgContext, 1);
 
63
      g_static_private_set(&msg_context_private, context, g_free);
 
64
    }
 
65
  return context;
 
66
}
 
67
 
 
68
void
 
69
msg_set_context(LogMessage *msg)
 
70
{
 
71
  MsgContext *context = msg_get_context();
 
72
  
 
73
  if (msg && (msg->flags & LF_INTERNAL))
 
74
    {
 
75
      context->recurse_count = msg->recurse_count + 1;
 
76
    }
 
77
  else
 
78
    {
 
79
      context->recurse_count = 0;
 
80
    }
 
81
}
 
82
 
 
83
#define MAX_RECURSIONS 1
 
84
 
 
85
gboolean
 
86
msg_limit_internal_message(void)
 
87
{
 
88
  MsgContext *context;
 
89
  
 
90
  if (!evt_context)
 
91
    return FALSE;
 
92
 
 
93
  context = msg_get_context();
 
94
  
 
95
  if (context->recurse_count > MAX_RECURSIONS)
 
96
    {
 
97
      if (!context->recurse_warning)
 
98
        {
 
99
          msg_event_send(
 
100
            msg_event_create(EVT_PRI_WARNING, "syslog-ng internal() messages are looping back, preventing loop by suppressing further messages", 
 
101
                             evt_tag_int("recurse_count", context->recurse_count),
 
102
                             NULL));
 
103
          context->recurse_warning = TRUE;
 
104
        }
 
105
      return FALSE;
 
106
    }
 
107
  return TRUE;
 
108
}
 
109
 
42
110
 
43
111
static void
44
112
msg_send_internal_message(int prio, const char *msg)
45
113
{
46
 
  gchar *buf;
47
 
  
48
 
  if (log_stderr || (!syslog_started && (prio & 0x7) <= EVT_PRI_WARNING))
 
114
  if (G_UNLIKELY(log_stderr || (!syslog_started && (prio & 0x7) <= EVT_PRI_WARNING)))
49
115
    {
50
116
      fprintf(stderr, "%s\n", msg);
51
117
    }
55
121
      
56
122
      if (G_LIKELY(internal_msg_queue))
57
123
        {
58
 
          buf = g_strdup_printf("<%d> syslog-ng[%d]: %s\n", prio, getpid(), msg);
59
 
          m = log_msg_new(buf, strlen(buf), NULL, LP_INTERNAL | LP_LOCAL, NULL);
60
 
          g_queue_push_tail(internal_msg_queue, m);
61
 
          g_free(buf);
 
124
          MsgContext *context = msg_get_context();
 
125
 
 
126
          if (context->recurse_count == 0)
 
127
            context->recurse_warning = FALSE;
 
128
          m = log_msg_new_internal(prio, msg, LP_INTERNAL | LP_LOCAL);
 
129
          m->recurse_count = context->recurse_count;
 
130
          msg_queue_push(internal_msg_queue, m);
62
131
        }
63
132
    }
64
133
}
69
138
  EVTREC *e;
70
139
  va_list va;
71
140
  
 
141
  g_static_mutex_lock(&evtlog_lock);
72
142
  e = evt_rec_init(evt_context, prio, desc);
73
143
  if (tag1)
74
144
    {
77
147
      evt_rec_add_tagsv(e, va);
78
148
      va_end(va);
79
149
    }
 
150
  g_static_mutex_unlock(&evtlog_lock);
80
151
  return e;
81
152
}
82
153
 
84
155
msg_event_send(EVTREC *e)
85
156
{
86
157
  gchar *msg;
87
 
  /* this prevents infinite loops, debug messages causing 
88
 
   * internal messages causing debug messages again */
89
 
  if (evt_rec_get_syslog_pri(e) != EVT_PRI_DEBUG || log_stderr)
90
 
    {
91
 
      msg = evt_format(e);
92
 
      
 
158
  
 
159
  msg = evt_format(e);
 
160
  if (log_syslog)
 
161
    {
 
162
      syslog(evt_rec_get_syslog_pri(e), "%s", msg);
 
163
    }
 
164
  else
 
165
    {
93
166
      msg_send_internal_message(evt_rec_get_syslog_pri(e) | EVT_FAC_SYSLOG, msg); 
94
 
      free(msg);
95
167
    }
 
168
  free(msg);
 
169
  g_static_mutex_lock(&evtlog_lock);
96
170
  evt_rec_free(e);
 
171
  g_static_mutex_unlock(&evtlog_lock);
97
172
}
98
173
 
99
174
void
118
193
  syslog_started = TRUE;
119
194
}
120
195
 
121
 
gboolean
122
 
msg_init(int use_stderr)
 
196
void
 
197
msg_redirect_to_syslog(const gchar *program_name)
123
198
{
124
 
  internal_msg_queue = g_queue_new();
 
199
  log_syslog = TRUE;
 
200
  openlog(program_name, LOG_NDELAY | LOG_PID, LOG_SYSLOG);
 
201
}
125
202
 
126
 
  log_stderr = use_stderr;
 
203
void
 
204
msg_init(gboolean interactive)
 
205
{
 
206
  if (!interactive)
 
207
    {
 
208
      internal_msg_queue = msg_queue_new();
 
209
      g_log_set_handler(G_LOG_DOMAIN, 0xff, msg_log_func, NULL);
 
210
      g_log_set_handler("GLib", 0xff, msg_log_func, NULL);
 
211
    }
 
212
  else
 
213
    {
 
214
      log_stderr = TRUE;
 
215
    }
127
216
  evt_context = evt_ctx_init("syslog-ng", EVT_FAC_SYSLOG);
128
 
 
129
 
  g_log_set_handler(G_LOG_DOMAIN, 0xff, msg_log_func, NULL);
130
 
  g_log_set_handler("GLib", 0xff, msg_log_func, NULL);
131
 
  return TRUE;
132
217
}
133
218
 
134
219
 
136
221
msg_deinit()
137
222
{
138
223
  evt_ctx_free(evt_context);
139
 
  g_queue_free(internal_msg_queue);
140
 
  internal_msg_queue = NULL;
141
 
}
 
224
  if (internal_msg_queue)
 
225
    {
 
226
      msg_queue_free(internal_msg_queue);
 
227
      internal_msg_queue = NULL;
 
228
    }
 
229
}
 
230
 
 
231
static GOptionEntry msg_option_entries[] =
 
232
{
 
233
  { "verbose",           'v',         0, G_OPTION_ARG_NONE, &verbose_flag, "Be a bit more verbose", NULL },
 
234
  { "debug",             'd',         0, G_OPTION_ARG_NONE, &debug_flag, "Enable debug messages", NULL},
 
235
  { "trace",             't',         0, G_OPTION_ARG_NONE, &trace_flag, "Enable trace messages", NULL },
 
236
  { "stderr",            'e',         0, G_OPTION_ARG_NONE, &log_stderr,  "Log messages to stderr", NULL},
 
237
  { NULL }
 
238
};
 
239
 
 
240
void
 
241
msg_add_option_group(GOptionContext *ctx)
 
242
{
 
243
  GOptionGroup *group;
 
244
 
 
245
  group = g_option_group_new("log", "Log options", "Log options", NULL, NULL);
 
246
  g_option_group_add_entries(group, msg_option_entries);
 
247
  g_option_context_add_group(ctx, group);
 
248
}
 
249