Que tal adicionar emojis por LOGLEVEL no printk
do Kernel Linux? "Por um dmesg
mais moderno 💪". Bem, essa foi a minha diversão do final de semana:
Como todo bom sistema de log, o do Kernel Linux também tem os níveis de logs. Eles estão definidos no include/linux/kern_levels.h
:
/* integer equivalents of KERN_<LEVEL> */
#define LOGLEVEL_SCHED -2 /* Deferred messages from sched code
* are set to this special level */
#define LOGLEVEL_DEFAULT -1 /* default (or last) loglevel */
#define LOGLEVEL_EMERG 0 /* system is unusable */
#define LOGLEVEL_ALERT 1 /* action must be taken immediately */
#define LOGLEVEL_CRIT 2 /* critical conditions */
#define LOGLEVEL_ERR 3 /* error conditions */
#define LOGLEVEL_WARNING 4 /* warning conditions */
#define LOGLEVEL_NOTICE 5 /* normal but significant condition */
#define LOGLEVEL_INFO 6 /* informational */
#define LOGLEVEL_DEBUG 7 /* debug-level messages */
Utilizei dessas definições para adicionar os emojis durante a montagem do info_print_prefix
:
static size_t info_print_prefix(const struct printk_info *info, bool syslog,
bool time, char *buf)
{
size_t len = 0;
if (syslog)
len = print_syslog((info->facility << 3) | info->level, buf);
if (time)
len += print_time(info->ts_nsec, buf + len);
len += print_emoji(info->level, buf + len);
len += print_caller(info->caller_id, buf + len);
if (IS_ENABLED(CONFIG_PRINTK_CALLER) || time) {
buf[len++] = ' ';
buf[len] = '\0';
}
return len;
}
A função print_emoji
é chamada e adiciona o emoji, respectivo ao info->level
, depois do print_time
:
#ifdef CONFIG_PRINTK_EMOJI
static size_t print_emoji(unsigned int level, char *buf)
{
switch (level) {
case LOGLEVEL_EMERG:
return sprintf(buf, " %s", "🆘");
case LOGLEVEL_ALERT:
return sprintf(buf, " %s", "😲");
case LOGLEVEL_CRIT:
return sprintf(buf, " %s", "🔥");
case LOGLEVEL_ERR:
return sprintf(buf, " %s", "❌");
case LOGLEVEL_WARNING:
return sprintf(buf, " %s", "⚠️");
case LOGLEVEL_NOTICE:
return sprintf(buf, " %s", "📍");
case LOGLEVEL_INFO:
return sprintf(buf, " %s", "ℹ️");
case LOGLEVEL_DEBUG:
return sprintf(buf, " %s", "🪲");
default:
return sprintf(buf, " %s", "🤔");
}
}
#else
#define print_emoji(level, buf) 0
#endif
O info_print_prefix
é chamado pelo record_print_text
que no final irá montar o seguinte:
Outro ponto a se notar é que também adicionei uma nova config CONFIG_PRINTK_EMOJI
:
config PRINTK_EMOJI
default n
bool "Enable support for printk" if PRINTK
help
This option enables emojis prefix for printk log levels.
Para que o print_emoji
seja implementado o PRINTK_EMOJI
deve ser selecionado.
Se você quiser adicionar essa "funcionalidade" no seu Kernel Linux, aqui está o patch:
Talvez você tenha uma surpresa que mesmo com o patch aplicado, quando executar o comando dmesg
os emojis não serão apresentados 🤔:
Por padrão o dmesg
não pega os logs de Kernel do syslog(2)
, mas sim de /dev/kmsg
. Como minha implementação não modifica o printk_record->text_buf
, mas apenas adiciona mais uma "sessão" ao prefix, é esperado que os emojis não estejam no /dev/kmsg
. Para ter os emojis temos que pegar os logs de syslog(2)
. Pode ser lendo de /proc/kmsg
ou com dmesg --syslog
:
Se você já tem decorado toda a numeração de LOGLEVEL do Linux talvez o emoji não lhe traga nenhuma facilidade, usando o dmesg -r
é possível ver o LOGLEVEL no começo da linha:
Mas, se você é como eu, e geralmente esquece com frequência a numeração 😅, o emoji é uma facilidade interessante, é possível linkar a imagem ao nível de log facilmente.
"Ah, vamos adicionar emojis ao printk", parecia algo fácil, bobo. Mas o quanto eu aprendi sobre a arquitetura do sistema de logs do Kernel Linux implementado isso foi incrível.
Se eu vou fazer upstream dessa "funcionalidade"? Eu não sei, não estou convencido do real valor disso. Ou até mesmo se isso deveria estar do lado do Kernel. Talvez adicionar isso no próprio dmesg
, que ao ler o LOGLEVEL adicione o prefix com emoji, seja algo mais "certo" 😅.
O que você acha? Gostou, deixe me saber, me mande um alô nas minhas redes sociais: