Logging in Idris

Here’s the translation of the Go logging example to Idris, formatted in Markdown suitable for Hugo:

import System.File
import Data.String
import Data.List
import System.Clock

-- Simple logging function
log : String -> IO ()
log message = do
    time <- clockTime Monotonic
    putStrLn $ show time ++ ": " ++ message

-- Custom logger with prefix
data Logger = MkLogger String

newLogger : String -> Logger
newLogger prefix = MkLogger prefix

logWithPrefix : Logger -> String -> IO ()
logWithPrefix (MkLogger prefix) message = do
    time <- clockTime Monotonic
    putStrLn $ show time ++ " " ++ prefix ++ ": " ++ message

-- Main function to demonstrate logging
main : IO ()
main = do
    -- Simple logging
    log "standard logger"

    -- Logging with microsecond precision (simulated)
    time <- clockTime Monotonic
    let microTime = show time ++ ".123456"
    putStrLn $ microTime ++ ": with micro"

    -- Logging with file and line information (simulated)
    putStrLn "logging.idr:40: with file/line"

    -- Custom logger with prefix
    let myLogger = newLogger "my"
    logWithPrefix myLogger "from myLogger"

    -- Changing prefix of custom logger
    let myNewLogger = newLogger "ohmy"
    logWithPrefix myNewLogger "from myLogger"

    -- Logging to a buffer (simulated with a list)
    let bufferLog = []
    let bufferLog' = bufferLog ++ ["buf:2023/08/22 10:45:16 hello"]
    putStrLn $ "from buflog:" ++ (concat bufferLog')

    -- Structured logging (simulated)
    putStrLn """{"time":"2023-08-22T10:45:16.904166391-07:00","level":"INFO","msg":"hi there"}"""
    putStrLn """{"time":"2023-08-22T10:45:16.904178985-07:00","level":"INFO","msg":"hello again","key":"val","age":25}"""

This Idris code demonstrates basic logging concepts, adapting the Go example as closely as possible. Here’s an explanation of the key points:

  1. We define a simple log function that prints a timestamp and a message.

  2. A custom logger is implemented using a Logger data type and associated functions.

  3. The main function demonstrates various logging techniques:

    • Basic logging
    • Logging with simulated microsecond precision
    • Logging with simulated file and line information
    • Using a custom logger with a prefix
    • Changing the prefix of a custom logger
    • Simulating logging to a buffer using a list
    • Simulating structured logging by printing JSON-like strings
  4. Idris doesn’t have built-in JSON handling or microsecond precision in its standard library, so these are simulated for demonstration purposes.

  5. The clockTime function from System.Clock is used to get timestamps, though it doesn’t provide the same level of precision as Go’s logging package.

To run this program, save it as logging.idr and use the Idris compiler:

$ idris logging.idr -o logging
$ ./logging

The output will be similar to the Go example, but with Idris-specific timestamps and formatting.

Note that Idris is a purely functional language with dependent types, so some concepts from Go (like mutable state and side effects) are handled differently. This example focuses on demonstrating similar logging functionality rather than being a direct translation of the Go code.