aboutsummaryrefslogtreecommitdiffstats
path: root/alv/logger.moon
blob: 1564f11b0650b5b7a5229fd3c0900221fee2eaa6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
----
-- Logger implementation.
--
-- @classmod Logger
unpack or= table.unpack

export L
L or= setmetatable {}, __index: => ->

class Logger
  levels = {
    debug: 0
    trace: 1
    log:   2
    warn:  3
    print: 4
    error: 5
    silent: 6
  }

--- members
-- @section members

  --- push an indentation level and execute a function in it.
  -- @tparam function fn the function to execute
  -- @param ... parameters to `fn`
  push: (fn, ...) =>
    last = @prefix
    @prefix ..= '  '

    res = { xpcall fn, debug.traceback, ... }

    @prefix = last

    if ok = table.remove res, 1
      unpack res
    else
      error unpack res

  --- set the output time (runtime/evaltime).
  -- @tparam string time (`'eval'` or `'run'`)
  set_time: (time) =>
    @stream = switch time
      when 'eval' then io.stderr
      when 'run' then io.stdout
      else error "invalid time '#{time}'"

  --- write out a message (for internal use).
  -- @tparam string message
  put: (message) =>
    @stream\write message, '\n'
    @stream\flush!

--- static functions
-- @section static

  --- create a new Logger.
  -- @classmethod
  -- @tparam string level the log-level to log at.
  new: (level='log') =>
    @level = levels[level] or level
    @prefix = ''
    @set_time 'eval'

    for name, level in pairs levels
      @[name] = (msg) =>
        return unless @level <= level
        @put if @level == levels.debug
          where = debug.traceback '', 2
          "#{msg}\n#{where}"
        else
          tostring msg

    if level == levels.print
      @push = (fn, ...) => fn ...

  --- set up the global Logger singleton.
  --
  -- The available log-levels are:
  --
  -- - `'debug'`
  -- - `'trace'`
  -- - `'log'` (the default)
  -- - `'warn'`
  -- - `'error'`
  -- - `'print'`
  -- - `'silent'`
  --
  -- @tparam ?string level the level to initialize the logger at.
  @init: (...) =>
    L = @ ...

{
  :Logger
}