i3: Replace loglevels by a global debug logging
File-limited were not used nor really useful Besides, they are painful to maintain in Makefile rules compared to the benefit
This commit is contained in:
parent
1f682eb9c8
commit
bdc078914b
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,8 +1,6 @@
|
|||||||
*.o
|
*.o
|
||||||
tags
|
tags
|
||||||
include/loglevels.h
|
|
||||||
include/GENERATED_*.h
|
include/GENERATED_*.h
|
||||||
loglevels.tmp
|
|
||||||
*.swp
|
*.swp
|
||||||
*.gcda
|
*.gcda
|
||||||
*.gcno
|
*.gcno
|
||||||
|
36
Makefile
36
Makefile
@ -6,25 +6,15 @@ include $(TOPDIR)/common.mk
|
|||||||
AUTOGENERATED:=src/cfgparse.tab.c src/cfgparse.yy.c
|
AUTOGENERATED:=src/cfgparse.tab.c src/cfgparse.yy.c
|
||||||
FILES:=$(filter-out $(AUTOGENERATED),$(wildcard src/*.c))
|
FILES:=$(filter-out $(AUTOGENERATED),$(wildcard src/*.c))
|
||||||
FILES:=$(FILES:.c=.o)
|
FILES:=$(FILES:.c=.o)
|
||||||
HEADERS:=$(filter-out include/loglevels.h,$(wildcard include/*.h))
|
HEADERS:=$(wildcard include/*.h)
|
||||||
CMDPARSE_HEADERS:=include/GENERATED_call.h include/GENERATED_enums.h include/GENERATED_tokens.h
|
CMDPARSE_HEADERS:=include/GENERATED_call.h include/GENERATED_enums.h include/GENERATED_tokens.h
|
||||||
|
|
||||||
# Recursively generate loglevels.h by explicitly calling make
|
|
||||||
# We need this step because we need to ensure that loglevels.h will be
|
|
||||||
# updated if necessary, but we also want to save rebuilds of the object
|
|
||||||
# files, so we cannot let the object files depend on loglevels.h.
|
|
||||||
ifeq ($(MAKECMDGOALS),loglevels.h)
|
|
||||||
#UNUSED:=$(warning Generating loglevels.h)
|
|
||||||
else
|
|
||||||
UNUSED:=$(shell $(MAKE) loglevels.h)
|
|
||||||
endif
|
|
||||||
|
|
||||||
SUBDIRS:=i3-msg i3-input i3-nagbar i3-config-wizard i3bar i3-dump-log
|
SUBDIRS:=i3-msg i3-input i3-nagbar i3-config-wizard i3bar i3-dump-log
|
||||||
|
|
||||||
# Depend on the specific file (.c for each .o) and on all headers
|
# Depend on the specific file (.c for each .o) and on all headers
|
||||||
src/%.o: src/%.c ${HEADERS}
|
src/%.o: src/%.c ${HEADERS}
|
||||||
echo "[i3] CC $<"
|
echo "[i3] CC $<"
|
||||||
$(CC) $(CPPFLAGS) $(CFLAGS) -DLOGLEVEL="((uint64_t)1 << $(shell awk '/$(shell basename $< .c)/ { print NR; exit 0; }' loglevels.tmp))" -c -o $@ $<
|
$(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
all: i3 subdirs
|
all: i3 subdirs
|
||||||
|
|
||||||
@ -42,18 +32,6 @@ subdirs:
|
|||||||
$(MAKE) -C $$dir; \
|
$(MAKE) -C $$dir; \
|
||||||
done
|
done
|
||||||
|
|
||||||
loglevels.h:
|
|
||||||
echo "[i3] LOGLEVELS"
|
|
||||||
for file in $$(ls src/*.c src/*.y src/*.l | grep -v 'cfgparse.\(tab\|yy\).c'); \
|
|
||||||
do \
|
|
||||||
echo $$(basename $$file .c); \
|
|
||||||
done > loglevels.tmp
|
|
||||||
(echo "char *loglevels[] = {"; for file in $$(cat loglevels.tmp); \
|
|
||||||
do \
|
|
||||||
echo "\"$$file\", "; \
|
|
||||||
done; \
|
|
||||||
echo "};") > include/loglevels.h;
|
|
||||||
|
|
||||||
# The GENERATED_* files are actually all created from a single pass, so all
|
# The GENERATED_* files are actually all created from a single pass, so all
|
||||||
# files just depend on the first one.
|
# files just depend on the first one.
|
||||||
include/GENERATED_call.h: generate-command-parser.pl parser-specs/commands.spec
|
include/GENERATED_call.h: generate-command-parser.pl parser-specs/commands.spec
|
||||||
@ -67,19 +45,19 @@ include/GENERATED_tokens.h: include/GENERATED_call.h
|
|||||||
# and once as an object file for i3.
|
# and once as an object file for i3.
|
||||||
src/commands_parser.o: src/commands_parser.c ${HEADERS} ${CMDPARSE_HEADERS}
|
src/commands_parser.o: src/commands_parser.c ${HEADERS} ${CMDPARSE_HEADERS}
|
||||||
echo "[i3] CC $<"
|
echo "[i3] CC $<"
|
||||||
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -DTEST_PARSER -DLOGLEVEL="((uint64_t)1 << $(shell awk '/$(shell basename $< .c)/ { print NR; exit 0; }' loglevels.tmp))" -o test.commands_parser $< $(LIBS)
|
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -DTEST_PARSER -o test.commands_parser $< $(LIBS)
|
||||||
$(CC) $(CPPFLAGS) $(CFLAGS) -DLOGLEVEL="((uint64_t)1 << $(shell awk '/$(shell basename $< .c)/ { print NR; exit 0; }' loglevels.tmp))" -c -o $@ $<
|
$(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
src/cfgparse.yy.o: src/cfgparse.l src/cfgparse.y.o ${HEADERS}
|
src/cfgparse.yy.o: src/cfgparse.l src/cfgparse.y.o ${HEADERS}
|
||||||
echo "[i3] LEX $<"
|
echo "[i3] LEX $<"
|
||||||
$(FLEX) -i -o$(@:.o=.c) $<
|
$(FLEX) -i -o$(@:.o=.c) $<
|
||||||
$(CC) $(CPPFLAGS) $(CFLAGS) -DLOGLEVEL="(1 << $(shell awk '/cfgparse.l/ { print NR }' loglevels.tmp))" -c -o $@ $(@:.o=.c)
|
$(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $(@:.o=.c)
|
||||||
|
|
||||||
|
|
||||||
src/cfgparse.y.o: src/cfgparse.y ${HEADERS}
|
src/cfgparse.y.o: src/cfgparse.y ${HEADERS}
|
||||||
echo "[i3] YACC $<"
|
echo "[i3] YACC $<"
|
||||||
$(BISON) --debug --verbose -b $(basename $< .y) -d $<
|
$(BISON) --debug --verbose -b $(basename $< .y) -d $<
|
||||||
$(CC) $(CPPFLAGS) $(CFLAGS) -DLOGLEVEL="(1 << $(shell awk '/cfgparse.y/ { print NR }' loglevels.tmp))" -c -o $@ $(<:.y=.tab.c)
|
$(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $(<:.y=.tab.c)
|
||||||
|
|
||||||
|
|
||||||
install: all
|
install: all
|
||||||
@ -129,7 +107,7 @@ dist: distclean
|
|||||||
rm -rf i3-${VERSION}
|
rm -rf i3-${VERSION}
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f src/*.o src/*.gcno src/cmdparse.* src/cfgparse.tab.{c,h} src/cfgparse.yy.c src/cfgparse.{output,dot} loglevels.tmp include/loglevels.h include/GENERATED_*
|
rm -f src/*.o src/*.gcno src/cmdparse.* src/cfgparse.tab.{c,h} src/cfgparse.yy.c src/cfgparse.{output,dot} include/GENERATED_*
|
||||||
(which lcov >/dev/null 2>&1 && lcov -d . --zerocounters) || true
|
(which lcov >/dev/null 2>&1 && lcov -d . --zerocounters) || true
|
||||||
$(MAKE) -C libi3 clean
|
$(MAKE) -C libi3 clean
|
||||||
$(MAKE) -C docs clean
|
$(MAKE) -C docs clean
|
||||||
|
@ -141,7 +141,7 @@ src/load_layout.c::
|
|||||||
Contains code for loading layouts from JSON files.
|
Contains code for loading layouts from JSON files.
|
||||||
|
|
||||||
src/log.c::
|
src/log.c::
|
||||||
Handles the setting of loglevels, contains the logging functions.
|
Contains the logging functions.
|
||||||
|
|
||||||
src/main.c::
|
src/main.c::
|
||||||
Initializes the window manager.
|
Initializes the window manager.
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
* i3 - an improved dynamic tiling window manager
|
* i3 - an improved dynamic tiling window manager
|
||||||
* © 2009-2011 Michael Stapelberg and contributors (see also: LICENSE)
|
* © 2009-2011 Michael Stapelberg and contributors (see also: LICENSE)
|
||||||
*
|
*
|
||||||
* log.c: Setting of loglevels, logging functions.
|
* log.c: Logging functions.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#ifndef _LOG_H
|
#ifndef _LOG_H
|
||||||
@ -17,9 +17,8 @@
|
|||||||
is, delete the preceding comma */
|
is, delete the preceding comma */
|
||||||
#define LOG(fmt, ...) verboselog(fmt, ##__VA_ARGS__)
|
#define LOG(fmt, ...) verboselog(fmt, ##__VA_ARGS__)
|
||||||
#define ELOG(fmt, ...) errorlog("ERROR: " fmt, ##__VA_ARGS__)
|
#define ELOG(fmt, ...) errorlog("ERROR: " fmt, ##__VA_ARGS__)
|
||||||
#define DLOG(fmt, ...) debuglog(LOGLEVEL, "%s:%s:%d - " fmt, __FILE__, __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
#define DLOG(fmt, ...) debuglog("%s:%s:%d - " fmt, __FILE__, __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
||||||
|
|
||||||
extern char *loglevels[];
|
|
||||||
extern char *errorfilename;
|
extern char *errorfilename;
|
||||||
extern char *shmlogname;
|
extern char *shmlogname;
|
||||||
extern int shmlog_size;
|
extern int shmlog_size;
|
||||||
@ -32,10 +31,10 @@ extern int shmlog_size;
|
|||||||
void init_logging(void);
|
void init_logging(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enables the given loglevel.
|
* Set debug logging.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void add_loglevel(const char *level);
|
void set_debug_logging(const bool _debug_logging);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set verbosity of i3. If verbose is set to true, informative messages will
|
* Set verbosity of i3. If verbose is set to true, informative messages will
|
||||||
@ -47,10 +46,10 @@ void set_verbosity(bool _verbose);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs the given message to stdout while prefixing the current time to it,
|
* Logs the given message to stdout while prefixing the current time to it,
|
||||||
* but only if the corresponding debug loglevel was activated.
|
* but only if debug logging was activated.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void debuglog(uint64_t lev, char *fmt, ...);
|
void debuglog(char *fmt, ...);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs the given message to stdout while prefixing the current time to it.
|
* Logs the given message to stdout while prefixing the current time to it.
|
||||||
|
@ -31,7 +31,7 @@ void regex_free(struct regex *regex);
|
|||||||
/**
|
/**
|
||||||
* Checks if the given regular expression matches the given input and returns
|
* Checks if the given regular expression matches the given input and returns
|
||||||
* true if it does. In either case, it logs the outcome using LOG(), so it will
|
* true if it does. In either case, it logs the outcome using LOG(), so it will
|
||||||
* be visible without any debug loglevel.
|
* be visible without debug logging.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
bool regex_matches(struct regex *regex, const char *input);
|
bool regex_matches(struct regex *regex, const char *input);
|
||||||
|
@ -14,7 +14,7 @@ i3-dump-log [-s <socketpath>]
|
|||||||
== DESCRIPTION
|
== DESCRIPTION
|
||||||
|
|
||||||
Debug versions of i3 automatically use 1% of your RAM (but 25 MiB max) to store
|
Debug versions of i3 automatically use 1% of your RAM (but 25 MiB max) to store
|
||||||
full debug loglevel log output. This is extremely helpful for bugreports and
|
full debug log output. This is extremely helpful for bugreports and
|
||||||
figuring out what is going on, without permanently logging to a file.
|
figuring out what is going on, without permanently logging to a file.
|
||||||
|
|
||||||
With i3-dump-log, you can dump the SHM log to stdout.
|
With i3-dump-log, you can dump the SHM log to stdout.
|
||||||
|
@ -9,7 +9,7 @@ i3 - an improved dynamic, tiling window manager
|
|||||||
|
|
||||||
== SYNOPSIS
|
== SYNOPSIS
|
||||||
|
|
||||||
i3 [-a] [-c configfile] [-C] [-d <loglevel>] [-v] [-V]
|
i3 [-a] [-c configfile] [-C] [-d all] [-v] [-V]
|
||||||
|
|
||||||
== OPTIONS
|
== OPTIONS
|
||||||
|
|
||||||
@ -22,8 +22,9 @@ Specifies an alternate configuration file path.
|
|||||||
-C::
|
-C::
|
||||||
Check the configuration file for validity and exit.
|
Check the configuration file for validity and exit.
|
||||||
|
|
||||||
-d::
|
-d all::
|
||||||
Specifies the debug loglevel. To see the most output, use -d all.
|
Enables debug logging.
|
||||||
|
The 'all' parameter is present for historical reasons.
|
||||||
|
|
||||||
-v::
|
-v::
|
||||||
Display version number (and date of the last commit).
|
Display version number (and date of the last commit).
|
||||||
|
@ -427,11 +427,11 @@ struct CommandResult *parse_command(const char *input) {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Logs the given message to stdout while prefixing the current time to it,
|
* Logs the given message to stdout while prefixing the current time to it,
|
||||||
* but only if the corresponding debug loglevel was activated.
|
* but only if debug logging was activated.
|
||||||
* This is to be called by DLOG() which includes filename/linenumber
|
* This is to be called by DLOG() which includes filename/linenumber
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void debuglog(uint64_t lev, char *fmt, ...) {
|
void debuglog(char *fmt, ...) {
|
||||||
va_list args;
|
va_list args;
|
||||||
|
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
|
36
src/log.c
36
src/log.c
@ -4,7 +4,7 @@
|
|||||||
* i3 - an improved dynamic tiling window manager
|
* i3 - an improved dynamic tiling window manager
|
||||||
* © 2009-2011 Michael Stapelberg and contributors (see also: LICENSE)
|
* © 2009-2011 Michael Stapelberg and contributors (see also: LICENSE)
|
||||||
*
|
*
|
||||||
* log.c: Setting of loglevels, logging functions.
|
* log.c: Logging functions.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
@ -29,10 +29,7 @@
|
|||||||
#include "libi3.h"
|
#include "libi3.h"
|
||||||
#include "shmlog.h"
|
#include "shmlog.h"
|
||||||
|
|
||||||
/* loglevels.h is autogenerated at make time */
|
static bool debug_logging = false;
|
||||||
#include "loglevels.h"
|
|
||||||
|
|
||||||
static uint64_t loglevel = 0;
|
|
||||||
static bool verbose = false;
|
static bool verbose = false;
|
||||||
static FILE *errorfile;
|
static FILE *errorfile;
|
||||||
char *errorfilename;
|
char *errorfilename;
|
||||||
@ -146,26 +143,11 @@ void set_verbosity(bool _verbose) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Enables the given loglevel.
|
* Set debug logging.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void add_loglevel(const char *level) {
|
void set_debug_logging(const bool _debug_logging) {
|
||||||
/* Handle the special loglevel "all" */
|
debug_logging = _debug_logging;
|
||||||
if (strcasecmp(level, "all") == 0) {
|
|
||||||
loglevel = UINT64_MAX;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < sizeof(loglevels) / sizeof(char*); i++) {
|
|
||||||
if (strcasecmp(loglevels[i], level) != 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* The position in the array (plus one) is the amount of times
|
|
||||||
* which we need to shift 1 to the left to get our bitmask for
|
|
||||||
* the specific loglevel. */
|
|
||||||
loglevel |= (1 << (i+1));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -271,17 +253,17 @@ void errorlog(char *fmt, ...) {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Logs the given message to stdout while prefixing the current time to it,
|
* Logs the given message to stdout while prefixing the current time to it,
|
||||||
* but only if the corresponding debug loglevel was activated.
|
* but only if debug logging was activated.
|
||||||
* This is to be called by DLOG() which includes filename/linenumber
|
* This is to be called by DLOG() which includes filename/linenumber
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void debuglog(uint64_t lev, char *fmt, ...) {
|
void debuglog(char *fmt, ...) {
|
||||||
va_list args;
|
va_list args;
|
||||||
|
|
||||||
if (!logbuffer && !(loglevel & lev))
|
if (!logbuffer && !(debug_logging))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
vlog((loglevel & lev), fmt, args);
|
vlog(debug_logging, fmt, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
@ -318,8 +318,8 @@ int main(int argc, char *argv[]) {
|
|||||||
set_verbosity(true);
|
set_verbosity(true);
|
||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
LOG("Enabling debug loglevel %s\n", optarg);
|
LOG("Enabling debug logging\n");
|
||||||
add_loglevel(optarg);
|
set_debug_logging(true);
|
||||||
break;
|
break;
|
||||||
case 'l':
|
case 'l':
|
||||||
/* DEPRECATED, ignored for the next 3 versions (3.e, 3.f, 3.g) */
|
/* DEPRECATED, ignored for the next 3 versions (3.e, 3.f, 3.g) */
|
||||||
@ -367,12 +367,12 @@ int main(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
/* fall-through */
|
/* fall-through */
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "Usage: %s [-c configfile] [-d loglevel] [-a] [-v] [-V] [-C]\n", argv[0]);
|
fprintf(stderr, "Usage: %s [-c configfile] [-d all] [-a] [-v] [-V] [-C]\n", argv[0]);
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
fprintf(stderr, "\t-a disable autostart ('exec' lines in config)\n");
|
fprintf(stderr, "\t-a disable autostart ('exec' lines in config)\n");
|
||||||
fprintf(stderr, "\t-c <file> use the provided configfile instead\n");
|
fprintf(stderr, "\t-c <file> use the provided configfile instead\n");
|
||||||
fprintf(stderr, "\t-C validate configuration file and exit\n");
|
fprintf(stderr, "\t-C validate configuration file and exit\n");
|
||||||
fprintf(stderr, "\t-d <level> enable debug output with the specified loglevel\n");
|
fprintf(stderr, "\t-d all enable debug output\n");
|
||||||
fprintf(stderr, "\t-L <file> path to the serialized layout during restarts\n");
|
fprintf(stderr, "\t-L <file> path to the serialized layout during restarts\n");
|
||||||
fprintf(stderr, "\t-v display version and exit\n");
|
fprintf(stderr, "\t-v display version and exit\n");
|
||||||
fprintf(stderr, "\t-V enable verbose mode\n");
|
fprintf(stderr, "\t-V enable verbose mode\n");
|
||||||
|
@ -67,7 +67,7 @@ void regex_free(struct regex *regex) {
|
|||||||
/*
|
/*
|
||||||
* Checks if the given regular expression matches the given input and returns
|
* Checks if the given regular expression matches the given input and returns
|
||||||
* true if it does. In either case, it logs the outcome using LOG(), so it will
|
* true if it does. In either case, it logs the outcome using LOG(), so it will
|
||||||
* be visible without any debug loglevel.
|
* be visible without debug logging.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
bool regex_matches(struct regex *regex, const char *input) {
|
bool regex_matches(struct regex *regex, const char *input) {
|
||||||
|
Loading…
Reference in New Issue
Block a user