Implement shmlog command
Add shmlog command that takes <size>|toggle|on|off. Separate logbuffer management into open_logbuffer() and close_logbuffer(). Make t/187-commands-parser.t expect 'shmlog'. Add update_shmlog_atom() to update the SHMLOG_PATH. Document the shmlog command in userguide.
This commit is contained in:
parent
684a77442e
commit
f9d93d75b3
|
@ -1762,6 +1762,22 @@ stack-limit rows 5
|
||||||
image:stacklimit.png[Container limited to two columns]
|
image:stacklimit.png[Container limited to two columns]
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
== Starting/stopping/changing the size of the shm log
|
||||||
|
|
||||||
|
You may start or stop the shm log with +shmlog+, or change the size of the log.
|
||||||
|
If you pass a size to the shmlog command, it will change the running log's
|
||||||
|
size, or, if the log is not running, start the log with the provided size. You
|
||||||
|
may also toggle the log. This is useful if you want to bind the command to a
|
||||||
|
key.
|
||||||
|
|
||||||
|
*Examples*:
|
||||||
|
---------------
|
||||||
|
shmlog 26214400
|
||||||
|
shmlog toggle
|
||||||
|
shmlog on
|
||||||
|
shmlog off
|
||||||
|
---------------
|
||||||
|
|
||||||
=== Reloading/Restarting/Exiting
|
=== Reloading/Restarting/Exiting
|
||||||
|
|
||||||
You can make i3 reload its configuration file with +reload+. You can also
|
You can make i3 reload its configuration file with +reload+. You can also
|
||||||
|
|
|
@ -271,4 +271,10 @@ void cmd_rename_workspace(I3_CMD, char *old_name, char *new_name);
|
||||||
*/
|
*/
|
||||||
void cmd_bar(I3_CMD, char *bar_type, char *bar_value, char *bar_id);
|
void cmd_bar(I3_CMD, char *bar_type, char *bar_value, char *bar_id);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Implementation of 'shmlog <size>|toggle|on|off'
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void cmd_shmlog(I3_CMD, char *argument);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -38,6 +38,18 @@ extern int shmlog_size;
|
||||||
*/
|
*/
|
||||||
void init_logging(void);
|
void init_logging(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens the logbuffer.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void open_logbuffer(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes the logbuffer.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void close_logbuffer(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set debug logging.
|
* Set debug logging.
|
||||||
*
|
*
|
||||||
|
|
|
@ -108,6 +108,12 @@ void x_raise_con(Con *con, bool above_all);
|
||||||
*/
|
*/
|
||||||
void x_set_name(Con *con, const char *name);
|
void x_set_name(Con *con, const char *name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up the SHMLOG_PATH atom.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void update_shmlog_atom(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets up i3 specific atoms (I3_SOCKET_PATH and I3_CONFIG_PATH)
|
* Sets up i3 specific atoms (I3_SOCKET_PATH and I3_CONFIG_PATH)
|
||||||
*
|
*
|
||||||
|
|
|
@ -19,6 +19,7 @@ state INITIAL:
|
||||||
'exit' -> call cmd_exit()
|
'exit' -> call cmd_exit()
|
||||||
'restart' -> call cmd_restart()
|
'restart' -> call cmd_restart()
|
||||||
'reload' -> call cmd_reload()
|
'reload' -> call cmd_reload()
|
||||||
|
'shmlog' -> SHMLOG
|
||||||
'border' -> BORDER
|
'border' -> BORDER
|
||||||
'layout' -> LAYOUT
|
'layout' -> LAYOUT
|
||||||
'append_layout' -> APPEND_LAYOUT
|
'append_layout' -> APPEND_LAYOUT
|
||||||
|
@ -62,6 +63,12 @@ state EXEC:
|
||||||
command = string
|
command = string
|
||||||
-> call cmd_exec($nosn, $command)
|
-> call cmd_exec($nosn, $command)
|
||||||
|
|
||||||
|
# shmlog <size>|toggle|on|off
|
||||||
|
state SHMLOG:
|
||||||
|
# argument may be a number
|
||||||
|
argument = string
|
||||||
|
-> call cmd_shmlog($argument)
|
||||||
|
|
||||||
# border normal|none|1pixel|toggle|1pixel
|
# border normal|none|1pixel|toggle|1pixel
|
||||||
state BORDER:
|
state BORDER:
|
||||||
border_style = 'normal', 'pixel'
|
border_style = 'normal', 'pixel'
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
#include "all.h"
|
#include "all.h"
|
||||||
|
#include "shmlog.h"
|
||||||
|
|
||||||
// Macros to make the YAJL API a bit easier to use.
|
// Macros to make the YAJL API a bit easier to use.
|
||||||
#define y(x, ...) yajl_gen_ ## x (cmd_output->json_gen, ##__VA_ARGS__)
|
#define y(x, ...) yajl_gen_ ## x (cmd_output->json_gen, ##__VA_ARGS__)
|
||||||
|
@ -2027,3 +2028,34 @@ void cmd_bar(I3_CMD, char *bar_type, char *bar_value, char *bar_id) {
|
||||||
|
|
||||||
update_barconfig();
|
update_barconfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Implementation of 'shmlog <size>|toggle|on|off'
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void cmd_shmlog(I3_CMD, char *argument) {
|
||||||
|
if (!strcmp(argument,"toggle"))
|
||||||
|
/* Toggle shm log, if size is not 0. If it is 0, set it to default. */
|
||||||
|
shmlog_size = shmlog_size ? -shmlog_size : default_shmlog_size;
|
||||||
|
else if (!strcmp(argument, "on"))
|
||||||
|
shmlog_size = default_shmlog_size;
|
||||||
|
else if (!strcmp(argument, "off"))
|
||||||
|
shmlog_size = 0;
|
||||||
|
else {
|
||||||
|
/* If shm logging now, restart logging with the new size. */
|
||||||
|
if (shmlog_size > 0) {
|
||||||
|
shmlog_size = 0;
|
||||||
|
LOG("Restarting shm logging...\n");
|
||||||
|
init_logging();
|
||||||
|
}
|
||||||
|
shmlog_size = atoi(argument);
|
||||||
|
/* Make a weakly attempt at ensuring the argument is valid. */
|
||||||
|
if (shmlog_size <= 0)
|
||||||
|
shmlog_size = default_shmlog_size;
|
||||||
|
}
|
||||||
|
LOG("%s shm logging\n", shmlog_size > 0 ? "Enabling" : "Disabling");
|
||||||
|
init_logging();
|
||||||
|
update_shmlog_atom();
|
||||||
|
// XXX: default reply for now, make this a better reply
|
||||||
|
ysuccess(true);
|
||||||
|
}
|
||||||
|
|
33
src/log.c
33
src/log.c
|
@ -89,10 +89,21 @@ void init_logging(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* Start SHM logging if shmlog_size is > 0. shmlog_size is SHMLOG_SIZE by
|
||||||
|
* default on development versions, and 0 on release versions. If it is
|
||||||
|
* not > 0, the user has turned it off, so let's close the logbuffer. */
|
||||||
|
if (shmlog_size > 0 && logbuffer == NULL)
|
||||||
|
open_logbuffer();
|
||||||
|
else if (shmlog_size <= 0 && logbuffer)
|
||||||
|
close_logbuffer();
|
||||||
|
atexit(purge_zerobyte_logfile);
|
||||||
|
}
|
||||||
|
|
||||||
/* If this is a debug build (not a release version), we will enable SHM
|
/*
|
||||||
* logging by default, unless the user turned it off explicitly. */
|
* Opens the logbuffer.
|
||||||
if (logbuffer == NULL && shmlog_size > 0) {
|
*
|
||||||
|
*/
|
||||||
|
void open_logbuffer(void) {
|
||||||
/* Reserve 1% of the RAM for the logfile, but at max 25 MiB.
|
/* Reserve 1% of the RAM for the logfile, but at max 25 MiB.
|
||||||
* For 512 MiB of RAM this will lead to a 5 MiB log buffer.
|
* For 512 MiB of RAM this will lead to a 5 MiB log buffer.
|
||||||
* At the moment (2011-12-10), no testcase leads to an i3 log
|
* At the moment (2011-12-10), no testcase leads to an i3 log
|
||||||
|
@ -127,10 +138,8 @@ void init_logging(void) {
|
||||||
|
|
||||||
logbuffer = mmap(NULL, logbuffer_size, PROT_READ | PROT_WRITE, MAP_SHARED, logbuffer_shm, 0);
|
logbuffer = mmap(NULL, logbuffer_size, PROT_READ | PROT_WRITE, MAP_SHARED, logbuffer_shm, 0);
|
||||||
if (logbuffer == MAP_FAILED) {
|
if (logbuffer == MAP_FAILED) {
|
||||||
close(logbuffer_shm);
|
close_logbuffer();
|
||||||
shm_unlink(shmlogname);
|
|
||||||
fprintf(stderr, "Could not mmap SHM segment for the i3 log: %s\n", strerror(errno));
|
fprintf(stderr, "Could not mmap SHM segment for the i3 log: %s\n", strerror(errno));
|
||||||
logbuffer = NULL;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,8 +157,16 @@ void init_logging(void) {
|
||||||
logwalk = logbuffer + sizeof(i3_shmlog_header);
|
logwalk = logbuffer + sizeof(i3_shmlog_header);
|
||||||
loglastwrap = logbuffer + logbuffer_size;
|
loglastwrap = logbuffer + logbuffer_size;
|
||||||
store_log_markers();
|
store_log_markers();
|
||||||
}
|
}
|
||||||
atexit(purge_zerobyte_logfile);
|
|
||||||
|
/*
|
||||||
|
* Closes the logbuffer.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void close_logbuffer(void) {
|
||||||
|
close(logbuffer_shm);
|
||||||
|
shm_unlink(shmlogname);
|
||||||
|
logbuffer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
13
src/x.c
13
src/x.c
|
@ -1063,6 +1063,16 @@ void x_set_name(Con *con, const char *name) {
|
||||||
state->name = sstrdup(name);
|
state->name = sstrdup(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set up the I3_SHMLOG_PATH atom.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void update_shmlog_atom() {
|
||||||
|
xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root,
|
||||||
|
A_I3_SHMLOG_PATH, A_UTF8_STRING, 8,
|
||||||
|
strlen(shmlogname), shmlogname);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sets up i3 specific atoms (I3_SOCKET_PATH and I3_CONFIG_PATH)
|
* Sets up i3 specific atoms (I3_SOCKET_PATH and I3_CONFIG_PATH)
|
||||||
*
|
*
|
||||||
|
@ -1075,8 +1085,7 @@ void x_set_i3_atoms(void) {
|
||||||
xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root, A_I3_PID, XCB_ATOM_CARDINAL, 32, 1, &pid);
|
xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root, A_I3_PID, XCB_ATOM_CARDINAL, 32, 1, &pid);
|
||||||
xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root, A_I3_CONFIG_PATH, A_UTF8_STRING, 8,
|
xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root, A_I3_CONFIG_PATH, A_UTF8_STRING, 8,
|
||||||
strlen(current_configpath), current_configpath);
|
strlen(current_configpath), current_configpath);
|
||||||
xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root, A_I3_SHMLOG_PATH, A_UTF8_STRING, 8,
|
update_shmlog_atom();
|
||||||
strlen(shmlogname), shmlogname);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -144,7 +144,7 @@ is(parser_calls("\nworkspace test"),
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
is(parser_calls('unknown_literal'),
|
is(parser_calls('unknown_literal'),
|
||||||
"ERROR: Expected one of these tokens: <end>, '[', 'move', 'exec', 'exit', 'restart', 'reload', 'border', 'layout', 'append_layout', 'workspace', 'focus', 'kill', 'open', 'fullscreen', 'split', 'floating', 'mark', 'resize', 'rename', 'nop', 'scratchpad', 'mode', 'bar'\n" .
|
"ERROR: Expected one of these tokens: <end>, '[', 'move', 'exec', 'exit', 'restart', 'reload', 'shmlog', 'border', 'layout', 'append_layout', 'workspace', 'focus', 'kill', 'open', 'fullscreen', 'split', 'floating', 'mark', 'resize', 'rename', 'nop', 'scratchpad', 'mode', 'bar'\n" .
|
||||||
"ERROR: Your command: unknown_literal\n" .
|
"ERROR: Your command: unknown_literal\n" .
|
||||||
"ERROR: ^^^^^^^^^^^^^^^",
|
"ERROR: ^^^^^^^^^^^^^^^",
|
||||||
'error for unknown literal ok');
|
'error for unknown literal ok');
|
||||||
|
|
Loading…
Reference in New Issue