Stupid colored logging

Hello,

so, I did something very simple and silly, but I’m happy about it since it’s been useful when debugging tests: it’s a module that allows to print colored logging on the terminal (warning, it uses RGB ANSI escapes).

What is nice about it is simply that it is basically Debug.log, but also takes a “function name” as first argument, computes the hash of the function and prints it before the message… And the name is uniquely colored, so in the logs you’ll be able to quickly discern which rows belong to the same function.

You’d use it like Debug.log, with an additional function name as a first argument:

myFunction =
    clog "myFunction" "some message" returnValue

Here’s a screenshot to give you the idea:

image

Here’s the code, free to use as you like

module Logging exposing (..)


-- Debug log, in a separate function so it's easy to turn this off


color : Int -> Int -> Int -> String
color r g b =
    String.join "" [ "\u{001B}[38;2;", String.fromInt r, ";", String.fromInt g, ";", String.fromInt b, "m" ]



-- Stupid 24-bit hash of a string


hash24 : String -> Int
hash24 s =
    let
        -- Seed
        seed =
            7927

        -- Modulo, 24 bit
        mod =
            256 * 256 * 256

        hashFunc : Char -> Int -> Int
        hashFunc ch hashAcc =
            modBy mod <| Char.toCode ch + (hashAcc * seed)
    in
    s
        |> String.toList
        |> List.foldl hashFunc 131


u24tot3 : Int -> ( Int, Int, Int )
u24tot3 n =
    ( modBy 256 (n // 65536), modBy 256 (n // 256), modBy 256 n )



-- Colored logging: the function is hashed and colored uniquely


clog : String -> String -> x -> x
clog func msg val =
    let
        ( r, g, b ) =
            u24tot3 <| hash24 func
    in
    Debug.log
        (String.join "" [ color r g b, func, "\u{001B}[39m: ", msg ])
        val

Hope it’s useful!

This could be improved to give colors in a specific range instead of the full 24bit, that might help avoiding dark colors on dark terminals and similar issues.

5 Likes

I’ve been thinking about adding this to a script I’ve been writing. I guess it’s time to port it to elm-pages!

Now can someone please make an elm-review rule that automatically transforms Debug.log calls into clog calls (automatically adding the function name)? That would incredibly helpful.

What would be even cooler is if the colors could somehow reflect the structure of the code… something like hue being based on module, brightness on level of nesting or some such.

This is really cool! Also a little self promotion. If you don’t want to write those ANSI codes by hand elm-ansi 3.0.0.

1 Like

DIdn’t know about it, thank you!

Now, fust for fun, I’ll try and make a package for it since I never made one :smiley:

You might struggle with that a bit, since packages can’t contain references to the Debug module (which is one of the reasons we don’t have too many awesome debugging packages available :frowning: )

You could however make your module a port module, and instead of your clog function using Debug.log, it sends the string through a port to JS which prints it out using console.log.

And then you would be able to make your package.

I would make your package’s clog function take Debug.log as its first argument.

module Logging exposing (clog)

clog : (String -> x -> x) -> String -> String -> x -> x
clog debugLog func msg val =
    let
        ( r, g, b ) =
            u24tot3 <| hash24 func
    in
    debugLog
        (String.join "" [ color r g b, func, "\u{001B}[39m: ", msg ])
        val

Then a user would just need to do:

module SomeAppModule exposing (..)

import Logging

clog = 
    Logging.clog Debug.log

myFunction x = 
    clog "myFunction" "some message" x
3 Likes

That’s unfortunately not possible since ports are not allowed in packages (only in applications).

Oh yeah, I forgot about that :grinning:, sorry I should know better…

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.