neft
Version:
Universal Platform
247 lines (174 loc) • 5.67 kB
text/coffeescript
# Log
Access it with:
```javascript
const { log } = Neft;
```
'use strict'
utils = require 'src/utils'
assert = require 'src/assert'
{bind} = Function
{isArray} = Array
{unshift} = Array::
linesPrefix = ''
fromArgs = (args) ->
str = ''
str += "#{arg} → " for arg in args
str = str.substring 0, str.length - 3
lines = str.split '\n'
str = ''
for line in lines
str += "#{linesPrefix}#{line}\n"
str = str.slice 0, -1
str
callOnce = do ->
usedMessages = Object.create null
->
msg = fromArgs arguments
if usedMessages[msg]
return -1
usedMessages[msg] = true
@ arguments...
class Log
@LOGS_METHODS = ['log', 'info', 'warn', 'error', 'time', 'ok']
@MARKERS =
white: (str) -> "LOG: #{str}"
green: (str) -> "OK: #{str}"
gray: (str) -> "#{str}"
blue: (str) -> "INFO: #{str}"
yellow: (str) -> "WARN: #{str}"
red: (str) -> "ERROR: #{str}"
@setGlobalLinesPrefix = (prefix) ->
linesPrefix = prefix
@time = Date.now
@timeDiff = (since) -> Log.time() - since
constructor: (prefixes = [], @parentScope) ->
@prefixes = prefixes
assert.isArray prefixes
# bind all logs methods
args = utils.clone(prefixes)
args.unshift @
for name in @constructor.LOGS_METHODS
@[name] = bind.apply @[name], args
@[name].once = callOnce
@[key] = value for key, value of @
if typeof @['lo' + 'g'] is 'function'
func = =>
@log.apply func, arguments
func.once = callOnce
func.constructor = @constructor
return utils.merge func, @
_write: console?['lo' + 'g'].bind(console) or (->)
_writeError: console?['erro' + 'r'].bind(console) or (->)
## *Integer* log.LOG
## *Integer* log.INFO
## *Integer* log.OK
## *Integer* log.WARN
## *Integer* log.ERROR
## *Integer* log.TIME
## *Integer* log.ALL
i = 0
LOG: 1<<i++
INFO: 1<<i++
OK: 1<<i++
WARN: 1<<i++
ERROR: 1<<i++
TIME: 1<<i++
ALL: (1<<i++) - 1
## *Integer* enabled = `log.ALL`
Bitmask of the `log.LOG`, `INFO`, `OK`, `WARN`, `ERROR` and `TIME`.
enabled: @::ALL
isEnabled = (log, type) ->
unless log.enabled & type
false
else if log.parentScope
isEnabled log.parentScope, type
else
true
## log([*Any* messages...])
Prints the given messages into the console.
```javascript
log("Log me now!");
log("setName()", "db time");
// will be logged as "setName() → db time"
```
@::['log'] = ->
if isEnabled(@, @LOG)
@_write @constructor.MARKERS.white fromArgs arguments
return
## log.info([*Any* messages...])
Prints the given messages into the console with a blue color.
info: ->
if isEnabled(@, @INFO)
@_write @constructor.MARKERS.blue fromArgs arguments
return
## log.ok([*Any* messages...])
Prints the given messages into the console with a green color.
```javascript
log.ok("Data has been successfully sent!");
```
ok: ->
if isEnabled(@, @OK)
@_write @constructor.MARKERS.green fromArgs arguments
return
## log.warn([*Any* messages...])
Prints the given messages into the console with a yellow color.
```javascript
log.warn("Example warning with some recommendations");
```
warn: ->
if isEnabled(@, @WARN)
@_write @constructor.MARKERS.yellow fromArgs arguments
return
## log.error([*Any* messages...])
Prints the given messages into the console with a red color.
```javascript
log.error("Error occurs, ... in file ...");
```
error: ->
if isEnabled(@, @ERROR)
@_writeError @constructor.MARKERS.red fromArgs arguments
return
## *Array* log.time()
Returns an id used to measure execution time by the `log.end()` function.
```javascript
function findPath(){
var logtime = log.time('findPath()');
// ... some complex algorithm ...
log.end(logtime);
}
findPath();
```
time: ->
unless isEnabled(@, @TIME)
return -1
[@constructor.time(), fromArgs(arguments)]
## log.end(*Array* logTime)
Prints an information about the execution time for the given timer id.
end: (logTime) ->
diff = @constructor.timeDiff logTime[0]
diff = diff.toFixed 2
str = "#{logTime[1]}: #{diff} ms"
@_write @constructor.MARKERS.gray str
logTime[0] = 0
return
## log.scope([*Any* names...])
Returns a new `log` function.
All prints will be prefixed by the given names.
```javascript
var log = log.scope("Example file");
log("hello");
// "Example file → hello"
```
scope: (args...) ->
if @prefixes
unshift.apply args, @prefixes
new @constructor args, @
# implementation
impl = switch true
when utils.isNode
require './impls/node/index.coffee'
when utils.isBrowser
require './impls/browser/index.coffee'
LogImpl = if typeof impl is 'function' then impl Log else Log
exports = module.exports = new LogImpl
exports.Log = Log