aboutsummaryrefslogtreecommitdiffstats
path: root/logger.c
diff options
context:
space:
mode:
authormarkster <markster@f38db490-d61c-443f-a65b-d21fe96a405b>1999-12-05 07:28:29 +0000
committermarkster <markster@f38db490-d61c-443f-a65b-d21fe96a405b>1999-12-05 07:28:29 +0000
commitfd791f2c742d5aefc7524cdc9c62622c4a6a7531 (patch)
tree4f27f20b1f4f90a4f96d99e993a1810fbcdebf6d /logger.c
parent18438e3e7ffb91177ce68e3b68e08e4fd260c965 (diff)
Version 0.1.0 from FTP
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@92 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'logger.c')
-rwxr-xr-xlogger.c204
1 files changed, 204 insertions, 0 deletions
diff --git a/logger.c b/logger.c
new file mode 100755
index 000000000..b67c88f08
--- /dev/null
+++ b/logger.c
@@ -0,0 +1,204 @@
+/*
+ * Cheops Next Generation
+ *
+ * Mark Spencer <markster@marko.net>
+ *
+ * Copyright(C) 1999, Adtran, Inc.
+ *
+ * Distributed under the terms of the GNU General Public License (GPL) Version 2
+ *
+ * Logging routines
+ *
+ */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <time.h>
+#include <asterisk/logger.h>
+#include <asterisk/options.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <pthread.h>
+#include <sys/stat.h>
+#include "asterisk.h"
+
+#define AST_EVENT_LOG AST_LOG_DIR "/" EVENTLOG
+
+#define MAX_MSG_QUEUE 200
+
+static pthread_mutex_t msglist_lock = PTHREAD_MUTEX_INITIALIZER;
+
+static struct msglist {
+ char *msg;
+ struct msglist *next;
+} *list = NULL, *last = NULL;
+
+static int msgcnt = 0;
+
+static FILE *eventlog = NULL;
+
+static char *levels[] = {
+ "DEBUG",
+ "EVENT",
+ "NOTICE",
+ "WARNING",
+ "ERROR"
+};
+
+static struct verb {
+ void (*verboser)(char *string, int opos, int replacelast, int complete);
+ struct verb *next;
+} *verboser = NULL;
+
+int init_logger(void)
+{
+
+ mkdir(AST_LOG_DIR, 0755);
+ eventlog = fopen(AST_EVENT_LOG, "a");
+ if (eventlog) {
+ ast_log(LOG_EVENT, "Started Asterisk Event Logger\n");
+ if (option_verbose)
+ ast_verbose("Asterisk Event Logger Started\n");
+ return 0;
+ } else
+ ast_log(LOG_ERROR, "Unable to create event log: %s\n", strerror(errno));
+ return -1;
+}
+
+extern void ast_log(int level, char *file, int line, char *function, char *fmt, ...)
+{
+ char date[256];
+ time_t t;
+ struct tm *tm;
+
+ va_list ap;
+ va_start(ap, fmt);
+
+ if (level == 1 /* Event */) {
+ time(&t);
+ tm = localtime(&t);
+ if (tm) {
+ /* Log events into the event log file, with a different format */
+ strftime(date, sizeof(date), "%b %e %T", tm);
+ fprintf(eventlog, "%s asterisk[%d]: ", date, getpid());
+ vfprintf(eventlog, fmt, ap);
+ fflush(eventlog);
+ } else
+ ast_log(LOG_WARNING, "Unable to retrieve local time?\n");
+ } else {
+ fprintf(stdout, "%s: File %s, Line %d (%s): ", levels[level], file, line, function);
+ vfprintf(stdout, fmt, ap);
+ fflush(stdout);
+ }
+ va_end(ap);
+}
+
+extern void ast_verbose(char *fmt, ...)
+{
+ static char stuff[256];
+ static int pos = 0, opos;
+ static int replacelast = 0, complete;
+ struct msglist *m;
+ struct verb *v;
+ va_list ap;
+ va_start(ap, fmt);
+ pthread_mutex_lock(&msglist_lock);
+ vsnprintf(stuff + pos, sizeof(stuff) - pos, fmt, ap);
+ opos = pos;
+ pos = strlen(stuff);
+ if (fmt[strlen(fmt)-1] == '\n')
+ complete = 1;
+ else
+ complete=0;
+ if (complete) {
+ if (msgcnt < MAX_MSG_QUEUE) {
+ /* Allocate new structure */
+ m = malloc(sizeof(struct msglist));
+ msgcnt++;
+ } else {
+ /* Recycle the oldest entry */
+ m = list;
+ list = list->next;
+ free(m->msg);
+ }
+ if (m) {
+ m->msg = strdup(stuff);
+ if (m->msg) {
+ if (last)
+ last->next = m;
+ else
+ list = m;
+ m->next = NULL;
+ last = m;
+ } else {
+ msgcnt--;
+ ast_log(LOG_DEBUG, "Out of memory\n");
+ free(m);
+ }
+ }
+ }
+ if (verboser) {
+ v = verboser;
+ while(v) {
+ v->verboser(stuff, opos, replacelast, complete);
+ v = v->next;
+ }
+ } else
+ fprintf(stdout, stuff + opos);
+
+ if (fmt[strlen(fmt)-1] != '\n')
+ replacelast = 1;
+ else
+ replacelast = pos = 0;
+
+ va_end(ap);
+ pthread_mutex_unlock(&msglist_lock);
+}
+
+
+int ast_register_verbose(void (*v)(char *string, int opos, int replacelast, int complete))
+{
+ struct msglist *m;
+ struct verb *tmp;
+ /* XXX Should be more flexible here, taking > 1 verboser XXX */
+ if ((tmp = malloc(sizeof (struct verb)))) {
+ tmp->verboser = v;
+ pthread_mutex_lock(&msglist_lock);
+ tmp->next = verboser;
+ verboser = tmp;
+ m = list;
+ while(m) {
+ /* Send all the existing entries that we have queued (i.e. they're likely to have missed) */
+ v(m->msg, 0, 0, 1);
+ m = m->next;
+ }
+ pthread_mutex_unlock(&msglist_lock);
+ return 0;
+ }
+ return -1;
+}
+
+int ast_unregister_verbose(void (*v)(char *string, int opos, int replacelast, int complete))
+{
+ int res = -1;
+ struct verb *tmp, *tmpl=NULL;
+ pthread_mutex_lock(&msglist_lock);
+ tmp = verboser;
+ while(tmp) {
+ if (tmp->verboser == v) {
+ if (tmpl)
+ tmpl->next = tmp->next;
+ else
+ verboser = tmp->next;
+ break;
+ }
+ tmpl = tmp;
+ tmp = tmp->next;
+ }
+ if (tmp)
+ res = 0;
+ pthread_mutex_unlock(&msglist_lock);
+ return res;
+}