Skip to content

Instantly share code, notes, and snippets.

@brandonbloom
Created March 26, 2012 23:50
Show Gist options
  • Save brandonbloom/2210783 to your computer and use it in GitHub Desktop.
Save brandonbloom/2210783 to your computer and use it in GitHub Desktop.
# This module intentionally minimizes dependencies to mitigate breakage risk.
# Subset of Syslog's numerical severity codes (RFC 3164, Table 2)
SEVERITY =
ERROR: 3
WARN: 4
INFO: 6
DEBUG: 7
# Configuration
if CONFIG.DEBUG
STORE_LEVEL = SEVERITY.DEBUG
PRINT_LEVEL = SEVERITY.DEBUG
ALERT_LEVEL = -1
BUFFER_SIZE = 3000
else
STORE_LEVEL = SEVERITY.INFO
PRINT_LEVEL = SEVERITY.WARN
ALERT_LEVEL = SEVERITY.ERROR
BUFFER_SIZE = 200
# Syslog recommends a message limit of 2048 octets with UTF-8 encoding.
# Lower limit accomodates multi-byte chars; server may truncate a second time.
MAX_MESSAGE_LENGTH = 1024
# A ring buffer of log messages.
buffer = do ->
array = new Array(BUFFER_SIZE)
index = 0
count = 0
append: (object) ->
array[index] = object
index = (index + 1) % BUFFER_SIZE
count++ if count < BUFFER_SIZE
toArray: ->
(array[(index + i) % count] for i in [0...count])
dump = ->
buffer.toArray().join('\n')
exports.printLogs = ->
console.log dump()
postAlert = ->
$.post '/alert', logs: dump()
exports.scheduleAlert = scheduleAlert = do ->
ALERT_INTERVAL = 3000
alert = null
alertTimeout = null
->
# This mutually-recursive craziness limits the rate of alerts, but
# ensures that the first and last alert of each interval is sent.
alert = ->
alert = null
alertTimeout = setTimeout(onTimeout, ALERT_INTERVAL)
postAlert()
onTimeout = ->
alertTimeout = null
alert?()
alert() unless alertTimeout
# Define the global `log` object.
window.log = {}
_.each SEVERITY, (code, name) ->
format = (message) ->
unless _.isString(message)
try
message = JSON.stringify(message)
catch e
return log.error('Unable to stringify logged object')
message = "#{name} #{Date()} #{message.replace('\n', '')}"
if message.length > MAX_MESSAGE_LENGTH
message.substring(0, MAX_MESSAGE_LENGTH - 3) + '...'
else
message
log[name.toLowerCase()] = (message) ->
message = format(message)
buffer.append message if code <= STORE_LEVEL
console?.log message if code <= PRINT_LEVEL
scheduleAlert() if code <= ALERT_LEVEL
message
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment