Add logging infrastructure
authorŁukasz Stelmach <l.stelmach@samsung.com>
Mon, 8 May 2017 20:56:21 +0000 (22:56 +0200)
committerKrzysztof Opasiak <k.opasiak@samsung.com>
Tue, 9 May 2017 11:40:23 +0000 (13:40 +0200)
src/util/log.c [new file with mode: 0644]
src/util/log.h [new file with mode: 0644]

diff --git a/src/util/log.c b/src/util/log.c
new file mode 100644 (file)
index 0000000..0bdb79c
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * This file is a part of faultd.
+ *
+ * Copyright © 2017 Samsung Electronics
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define _GNU_SOURCE 1
+
+#include <assert.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <syslog.h>
+
+#include "log.h"
+#include "common.h"
+
+#define PROTECT_ERRNO __attribute__((cleanup(_reset_errno))) __attribute((unused)) int _saved_errno = errno
+
+static int log_max_level = LOG_INFO;
+
+static inline void _reset_errno(int *saved_errno) {
+  errno = *saved_errno;
+}
+
+int log_get_max_level() {
+  return log_max_level;
+}
+
+void log_set_max_level(int level) {
+  assert((level & LOG_PRIMASK) == level);
+  log_max_level = level;
+}
+
+int log_parse_level_name(const char *name) {
+  size_t i;
+  static const char *levels[] = {
+    [LOG_EMERG] = "emerg",
+    [LOG_ALERT] = "alert",
+    [LOG_CRIT] = "crit",
+    [LOG_ERR] = "err",
+    [LOG_WARNING] = "warning",
+    [LOG_NOTICE] = "notice",
+    [LOG_INFO] = "info",
+    [LOG_DEBUG] = "debug",
+  };
+
+  for (i = 0; i < ARRAY_SIZE(levels); i++)
+    if (strcmp(levels[i], name) == 0)
+      return i;
+  return -EINVAL;
+}
+
+int log_internal(int level,
+                 int error,
+                 const char *file,
+                 int line,
+                 const char* func,
+                 const char* format, ...) {
+  char buffer[LINE_MAX];
+  va_list ap;
+  PROTECT_ERRNO;
+
+  if (error < 0)
+    error = -error;
+
+  if (LOG_PRI(level) > log_max_level)
+    return -error;
+
+  if (error != 0)
+    errno = error;
+
+  va_start(ap, format);
+  vsnprintf(buffer, sizeof(buffer), format, ap);
+  va_end(ap);
+
+  fprintf(stderr, "<%d>:%s:%d:%s:%s\n", level, file, line, func, buffer);
+  return -error;
+}
diff --git a/src/util/log.h b/src/util/log.h
new file mode 100644 (file)
index 0000000..f5b4b4d
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef _FAULTD_LOG_H
+#define _FAULTD_LOG_H
+
+#include <stdlib.h>
+#include <syslog.h>
+
+#define log_full_errno(level, error, ...)                               \
+  ({                                                                    \
+    int _l = (level), _e = error;                                       \
+    (LOG_PRI(_l) <= log_get_max_level())                                \
+      ? log_internal(_l, _e, __FILE__, __LINE__, __FUNCTION__, __VA_ARGS__) \
+      : -abs(_e);                                                       \
+  })
+
+#define log_full(level, ...) log_full_errno(level, 0, __VA_ARGS__)
+
+#define log_debug(...)                log_full(LOG_DEBUG,   __VA_ARGS__)
+#define log_info(...)                 log_full(LOG_INFO,    __VA_ARGS__)
+#define log_notice(...)               log_full(LOG_NOTICE,  __VA_ARGS__)
+#define log_warning(...)              log_full(LOG_WARNING, __VA_ARGS__)
+#define log_error(...)                log_full(LOG_ERR,     __VA_ARGS__)
+
+#define log_debug_errno(error, ...)   log_full_errno(LOG_DEBUG,   error, __VA_ARGS__)
+#define log_info_errno(error, ...)    log_full_errno(LOG_INFO,    error, __VA_ARGS__)
+#define log_notice_errno(error, ...)  log_full_errno(LOG_NOTICE,  error, __VA_ARGS__)
+#define log_warning_errno(error, ...) log_full_errno(LOG_WARNING, error, __VA_ARGS__)
+#define log_error_errno(error, ...)   log_full_errno(LOG_ERR,     error, __VA_ARGS__)
+
+int log_get_max_level(void);
+void log_set_max_level(int level);
+int log_internal(int level, int error, const char *file, int __line, const char *func, const char *format, ...) __attribute__ ((format (printf, 6, 7)));
+int log_parse_level_name(const char* name);
+#endif  /* _FAUTLD_LOG_H */