How about adding emojis by LOGLEVEL in Linux Kernel printk? "For a more modern dmesg 💪". Well, that was my fun for the weekend:

Implementation

Like any good logging system, the Linux Kernel also has log levels. They are defined in 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 */

I used these definitions to add the emojis during the assembly of the 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;
}

The print_emoji function is called and adds the emoji, corresponding to the info->level, after the 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

The info_print_prefix is called by the record_print_text which in the end will assemble the following:

Another point to note is that I also added a new CONFIG_PRINTK_EMOJI config:

config PRINTK_EMOJI
    default n
    bool "Enable support for printk" if PRINTK
    help
      This option enables emojis prefix for printk log levels.

In order for print_emoji to be implemented PRINTK_EMOJI must be selected.

If you want to add this "feature" to your Linux Kernel, here is the patch:

kernel: printk: Add printk prefix with emoji by log level · microhobby/linus-tree@261071b (github.com)

Emojis in dmesg

You might be surprised that even with the patch applied, when you run the dmesg command the emojis will not be displayed 🤔:

By default dmesg does not get Kernel logs from syslog(2), but from /dev/kmsg. As my implementation doesn't modify the printk_record->text_buf, but just adds one more "session" to the prefix, it is expected that the emojis are not in /dev/kmsg. To get the emojis we have to get the logs from syslog(2). It can be read from /proc/kmsg or with dmesg --syslog:

Conclusions

If you have already memorized all the LOGLEVEL numbering from the Kernel maybe the emoji doesn't bring you any ease, using dmesg -r you can see the LOGLEVEL prefix at the beginning of the line:

But if you're like me, and you often forget the numbering 😅, the emoji is an interesting facility, you can link the image to the log level easily.

"Oh, let's add emojis to printk" seemed like an easy, silly thing to do. But how much I learned about the architecture of the Linux Kernel logging system implemented this was amazing.

Am I going to upstream this "feature"? I don't know, I'm not convinced of the real value of it. Or even if it should be on the Kernel side. Maybe adding this to the dmesg itself, which when reading LOGLEVEL adds the prefix with emoji, is something more "right to do" 😅.

What do you think? Liked? Let me know, say a hello on my social networks:












Categories: Linux