Debug, Trace, Warn, Error-Ausgaben

lano

Aktives Mitglied
Moin.

Ich überlege wie ich am besten Meldungen aus dem Programm ausgeben lassen kann.
Ich hab das ganze mal LOGLEVEL genannt, aber um die syslog oder vgl gehts mir gar nicht.
Ich will das Programm einfach nur gesprächiger machen.
Das hab ich mir so überlegt:
LOGLEVEL_TRACE 6
LOGLEVEL_DEBUG 5
LOGLEVEL_INFO 4
LOGLEVEL_WARN 3
LOGLEVEL_ERROR 2
LOGLEVEL_FATAL 1

debug.h:
#ifndef _DEBUG_H
#define _DEBUG_H

extern int debug;

#define LOGLEVEL_TRACE 6
#define LOGLEVEL_DEBUG 5
#define LOGLEVEL_INFO 4
#define LOGLEVEL_WARN 3
#define LOGLEVEL_ERROR 2
#define LOGLEVEL_FATAL 1
#define LOGLEVEL_OFF 0

extern void dbprintf(int loglevel, const char *fmt, ...);

#endif
debug.c:
#include "debug.h"
#include <stdarg.h> /* va_end(), va_list, va_start(), vprintf() */
#include <stdio.h>  /* vprintf() */

int debug = LOGLEVEL_OFF;

void dbprintf(int loglevel, const char *fmt, ...) {
  if (loglevel <= debug) {
    va_list ap;
    va_start(ap, fmt);
    vprintf(fmt, ap);
    va_end(ap);
  }
}

Im eigentlichen Programm sieht das dann quasi so aus:
dbprintf(LOGLEVEL_FATAL, "Cannot open database: %s\n", sqlite3_errmsg(db));

Dem Programm geb ich das gewünschte Level einfach als Argument mit. --log 4 zB
Man könnte auch --log-warn --log-fatal usw nehmen aber egal.

Nu frag ich mich ob ich das nicht kombinieren könnte. Im Moment wird ja alles kleiner gleich dem Loglevel ausgegeben.
Würde das überhaupt sinn machen?
 
Sind halt 2 unterschiedliche Herangehensweisen. Verschiedene Schweregrade zu definieren und alles was <= ist reinzunehmen ist eine Möglichkeit.
In logisch zusammengehörige Kategorien zu unterscheiden und diese ggf. zu kombinieren, wäre eine andere. Letzteres kannst du mit Flags erledigen. Die sind Zweierpotenzen (1,2,4,8,16,...) und lassen sich in einem Bitset kombinieren (bspw. eine Variable vom Typ unsigned int). Flag setzen mit |, prüfen ob Flag gesetzt wurde mit &.
Bsp:
C:
#define ERR_SERVER 1
#define ERR_CLIENT 2
#define ERR_SQL 4

// ...

unsigned flags = 0U;

flags |= ERR_SERVER;
flags |= ERR_SQL;

// ...

if (flags & ERR_SERVER)
  puts("server flag set");
else
  puts("server flag not set");

if (flags & ERR_CLIENT)
  puts("client flag set");
else
  puts("client flag not set");

Kannst aber auch beides miteinander kombinieren. Also nur Serverfehler ab einem bestimmtem Schweregrad reporten etc.
 
Ich möchte an dieser Stelle dazu raten, eine fertige Logging-Bibliothek zu benutzen, wenn es bei dem Projekt nicht spezifisch darum geht, mal unbedingt Logging zu implementieren.
Man kann dabei eine Menge falsch machen, und es ist in jedem Fall viel Boilerplate-Code den andere schon für dich geschrieben haben.
rxi-log ist da ein Beispiel, das auch Schweregrade umsetzt und in den Logging-Funktionen gleich auch printf-Funktionalitäten mitbringt.

MfG,
Lowl3v3l
 
Zurück
Oben Unten