summaryrefslogtreecommitdiff
path: root/src/log.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/log.c')
-rw-r--r--src/log.c276
1 files changed, 276 insertions, 0 deletions
diff --git a/src/log.c b/src/log.c
new file mode 100644
index 0000000..7b03550
--- /dev/null
+++ b/src/log.c
@@ -0,0 +1,276 @@
+/* See LICENSE file for copyright and license details. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include "log.h"
+
+#define DBG_LVL 0
+#define INF_LVL 1
+#define WRN_LVL 2
+#define ERR_LVL 3
+
+#define BUFF_SIZE 256
+#define HALF_SIZE (BUFF_SIZE / 2 - 1)
+
+/* Checks if the terminal supports colors */
+static int
+check_term_colors()
+{
+ FILE *fp;
+ char path[1024];
+
+ /* Open the command for reading. */
+ fp = popen("echo $COLORTERM", "r");
+ if (fp == NULL) {
+ printf("Failed to run command\n" );
+ exit(1);
+ }
+
+ /* Read the output a line at a time - output it. */
+ while (fgets(path, sizeof(path), fp) != NULL) {
+ /* printf("%s", path); */
+ if (strcmp(path, "truecolor\n") == 0) {
+ pclose(fp);
+ return 0;
+ }
+ }
+
+ /* close */
+ pclose(fp);
+
+ return -1;
+}
+
+/* Converts the property values */
+static int
+log_parse_level_property(char *str_level)
+{
+ if (strcmp( str_level, "DEBUG" ) == 0) return DBG_LVL;
+ if (strcmp( str_level, "INFO" ) == 0) return INF_LVL;
+ if (strcmp( str_level, "WARNING" ) == 0) return WRN_LVL;
+ if (strcmp( str_level, "ERROR" ) == 0) return ERR_LVL;
+
+ return -1;
+}
+
+static int
+strends(const char *str1, const char *str2)
+{
+ int str1_s = strlen(str1);
+ int str2_s = strlen(str2);
+ int i, offset;
+
+ if (str1_s < str2_s) {
+ /* str2 is longer than str1, so str1 doesn't contain str2 */
+ return 1;
+ }
+
+ offset = str1_s - str2_s;
+
+ for (i = str1_s - 1; i <= offset; i++) {
+ if (str1[i] != str2[i - offset]) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static int
+strstarts(const char *str1, const char *str2)
+{
+ int str1_s = strlen(str1);
+ int str2_s = strlen(str2);
+ int i;
+
+ if (str1_s < str2_s) {
+ /* str2 is longer than str1, so str1 doesn't contain str2 */
+ return 1;
+ }
+
+ for (i = 0; i < str2_s; i++) {
+ if (str1[i] != str2[i]) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static int
+stridxof(const char *str, char c)
+{
+ int size_s = strlen(str);
+ int i;
+
+ for (i = 0; i < size_s; i++) {
+ if (str[i] == c) {
+ return i;
+ }
+ }
+
+ return size_s - 1;
+}
+
+static char *
+remove_ext(const char *filename)
+{
+ int i, size_s = stridxof(filename, '.') + 1;
+ char *name = (char *) malloc(sizeof(char) * size_s);
+
+ for (i = 0; i < size_s; i++) {
+ name[i] = filename[i];
+ }
+
+ name[size_s - 1] = '\0';
+
+ return name;
+}
+
+/* Parses the configuration line to get log level and the context */
+static int
+log_get_level(const char *filename, char *conf_key, char *conf_value)
+{
+ int default_level = DBG_LVL;
+ const char *context;
+
+ if (strends(conf_key, "level") != 0)
+ return DBG_LVL;
+
+ context = remove_ext(filename);
+ printf("%s\n", conf_key);
+
+ if (strcmp(conf_key, "logging.level.default")) {
+ default_level = log_parse_level_property(conf_value);
+ } else if (strstarts(conf_key, "file.") == 0 && strends(conf_key, context) == 0) {
+ printf("Contesto: %s %s\n", context, conf_key);
+ }
+/*
+
+ char *key = strndup(conf_key, strlen(conf_key));
+ char *context = strndup(strtok(key, "."), strlen(key));
+ char *file_context = strndup(filename, HALF_SIZE);
+
+ int level = 0;
+
+ file_context = strtok(file_context, ".");
+
+ if (strends(key, "level") == 0) {
+ if (strcmp(context, "root") == 0) {
+ default_level = log_parse_level_property(conf_value);
+ } else if (strcmp(context, file_context) == 0
+ && (level = log_parse_level_property(conf_value)) >= 0) {
+ printf("----->>>> %d\n", level);
+ return level;
+ }
+ }*/
+
+ return default_level;
+}
+
+/* Initialize the log structure */
+static void
+log_init(Log *log)
+{
+ char conf_key[HALF_SIZE], conf_value[HALF_SIZE], buff[BUFF_SIZE];
+ FILE *file = fopen("log.config", "r");
+
+ /* Use the coded configuration */
+ if (file == NULL)
+ return;
+
+ while (fgets(buff, BUFF_SIZE, file) != NULL
+ && buff[0] != '#') {
+ sscanf(buff, "%[^=]=%s", conf_key, conf_value);
+
+ if (strends(conf_key, "level") == 0) {
+ log->level = log_get_level(log->filename, conf_key, conf_value);
+ }
+ }
+
+ printf("----->>>> %d\n", strstarts("file.main.level", "file"));
+
+ fclose(file);
+}
+
+Log *
+log_create(const char *filename) {
+ Log *log = (Log *) malloc(sizeof(Log));
+ log->filename = filename;
+ log->level = DBG_LVL;
+
+ log_init(log);
+
+ return log;
+}
+
+static void
+print_log(Log *log, int level, char *msg)
+{
+ time_t t;
+ struct tm *date;
+ const char *lvl;
+
+ /* Don't display log if the choosen level is major.
+ * For example: log->level is ERROR and level is INFO, only ERROR logs will be shown. */
+ if (log->level > level) return;
+
+ t = time(NULL);
+ date = localtime(&t);
+
+ switch (level) {
+ case DBG_LVL:
+ lvl = "[DEBUG]";
+ break;
+ case INF_LVL:
+ lvl = "[INFO]";
+ break;
+ case WRN_LVL:
+ lvl = "[WARNING]";
+ break;
+ case ERR_LVL:
+ lvl = "[ERROR]";
+ break;
+ default:
+ lvl = "[DEFAULT]";
+ break;
+ }
+
+ check_term_colors();
+ printf("%d-%02d-%02d %02d:%02d %10s: <%s> %s\n",
+ date->tm_year + 1900,
+ date->tm_mon,
+ date->tm_mday,
+ date->tm_hour,
+ date->tm_min,
+ lvl,
+ log->filename,
+ msg);
+}
+
+void
+log_debug(Log *log, char *msg)
+{
+ print_log(log, DBG_LVL, msg);
+}
+
+void
+log_error(Log *log, char *msg)
+{
+ print_log(log, ERR_LVL, msg);
+}
+
+void
+log_info(Log *log, char *msg)
+{
+ print_log(log, INF_LVL, msg);
+}
+
+void
+log_warn(Log *log, char *msg)
+{
+ print_log(log, WRN_LVL, msg);
+}