summaryrefslogtreecommitdiff
path: root/src/log.moon
blob: 3c54dc21ed29810673efd4a570e9fc8816cc2761 (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
-- Singleton object to deal with log messages
class log
	log: (message, tags, level) ->
		tags = tags or {}
		if not level
			error("Level is required")
		tag_rev = {tag,true for tag in *tags}
		chunk =
			level: level
			time: os.clock!
			message: message
			tags: tag_rev 
		stream_pos = log.messages + 1
		log.stream[stream_pos] = chunk
		for tag in *tags
			log.by_tags[tag] = log.by_tags[tag] or {}
			table.insert(log.by_tags[tag], stream_pos)
		log.by_level[level] = log.by_level[level] or {}
		table.insert(log.by_level[level], stream_pos)
		log.messages += 1
		for observer in *log.observers
			observer(chunk)
	
	reset: ->
		log.stream = {}
		log.messages = 0
		log.by_tags = {}
		log.by_level = {}
		log.observers = {}

	info: (message, tags) ->
		log.log(message, tags, "info")
	warn: (message, tags) ->
		log.log(message, tags, "warn")
	error: (message, tags) ->
		log.log(message, tags, "error")
	panic: (message, tags) ->
		log.log(message, tags, "panic")
	observe: (callback) ->
		table.insert(log.observers, callback)
	of_level: (level, callback) ->
		if not log.by_level[level]
			return
		for message_idx in *log.by_level[level]
			callback(log.stream[message_idx])
	of_tags: (tags, callback) ->
		if type(tags) ~= "table"
			tags = {tags}
		first_tag = tags[1]
		assert(type(first_tag) == "string", "tag was not a string, was a " .. type(first_tag))
		if not first_tag
			error("Must pass a tag")
		if not log.by_tags[first_tag]
			return
		for message_idx in *log.by_tags[first_tag]
			message = log.stream[message_idx]
			suitable = true
			for tag in *tags
				if not message.tags[tag]
					suitable = false
					break
			if suitable
				callback(message)

log.reset()
log