Logging in PureScript

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

module Main where

import Prelude

import Effect (Effect)
import Effect.Console (log)
import Data.DateTime (DateTime, adjust)
import Data.Time.Duration (Milliseconds(..))
import Data.Maybe (Maybe(..))
import Data.Formatter.DateTime (formatDateTime)
import Data.String (Pattern(..), split)

-- Simple logging function
simpleLog :: String -> Effect Unit
simpleLog message = log message

-- Logger with timestamp
logWithTimestamp :: String -> Effect Unit
logWithTimestamp message = do
  now <- getCurrentDateTime
  let timestamp = formatDateTime "YYYY/MM/DD HH:mm:ss" now
  log $ timestamp <> " " <> message

-- Logger with microsecond precision
logWithMicro :: String -> Effect Unit
logWithMicro message = do
  now <- getCurrentDateTime
  case adjust (Milliseconds 904.0) now of
    Just adjustedTime -> do
      let timestamp = formatDateTime "YYYY/MM/DD HH:mm:ss.SSSSSS" adjustedTime
      log $ timestamp <> " " <> message
    Nothing -> log message

-- Logger with file and line information
logWithFileAndLine :: String -> String -> Int -> String -> Effect Unit
logWithFileAndLine file line message = do
  now <- getCurrentDateTime
  let timestamp = formatDateTime "YYYY/MM/DD HH:mm:ss" now
  log $ timestamp <> " " <> file <> ":" <> show line <> ": " <> message

-- Custom logger with prefix
customLog :: String -> String -> Effect Unit
customLog prefix message = do
  now <- getCurrentDateTime
  let timestamp = formatDateTime "YYYY/MM/DD HH:mm:ss" now
  log $ prefix <> timestamp <> " " <> message

-- Structured logging (simplified version)
structuredLog :: String -> Array (String /\ String) -> Effect Unit
structuredLog message fields = do
  now <- getCurrentDateTime
  let timestamp = formatDateTime "YYYY-MM-DDTHH:mm:ss.SSSSSSZ" now
      fieldsStr = foldMap (\(k /\ v) -> "," <> k <> ":" <> v) fields
  log $ "{\"time\":\"" <> timestamp <> "\",\"level\":\"INFO\",\"msg\":\"" <> message <> "\"" <> fieldsStr <> "}"

main :: Effect Unit
main = do
  simpleLog "standard logger"
  
  logWithMicro "with micro"
  
  logWithFileAndLine "Main.purs" "40" "with file/line"
  
  customLog "my:" "from mylog"
  customLog "ohmy:" "from mylog"
  
  -- In PureScript, we don't have a direct equivalent to Go's bytes.Buffer
  -- Instead, we'll just log directly
  log "from buflog: buf:2023/08/22 10:45:16 hello"
  
  structuredLog "hi there" []
  structuredLog "hello again" ["key" /\ "val", "age" /\ "25"]

This PureScript code provides similar functionality to the Go example, with some adaptations due to language differences:

  1. We’ve created separate functions for different logging styles, as PureScript doesn’t have a built-in logging package with the same features as Go’s log package.

  2. The getCurrentDateTime function is assumed to exist (you’d need to implement this or use a library that provides it).

  3. For structured logging, we’ve created a simplified version that produces JSON-like output.

  4. PureScript doesn’t have a direct equivalent to Go’s bytes.Buffer, so we’ve simplified that part of the example.

  5. Error handling (like in the case of adjusting time) is done using PureScript’s Maybe type.

To run this program, you would need to compile it with the PureScript compiler and then execute it. The output would be similar to the Go example, with timestamps and structured logs.

Remember to install necessary dependencies like purescript-datetime, purescript-formatters, and others that provide the imported functions and types.

This example demonstrates basic logging techniques in PureScript, including adding timestamps, custom prefixes, and a simple form of structured logging.