pax_global_header00006660000000000000000000000064120541765010014513gustar00rootroot0000000000000052 comment=9441d9a23c45f4d98d90b19b6f5a9cb63c31c86d ain-1.1.1/000077500000000000000000000000001205417650100122625ustar00rootroot00000000000000ain-1.1.1/.gitignore000066400000000000000000000000431205417650100142470ustar00rootroot00000000000000/.project /.settings npm-debug.log ain-1.1.1/CHANGELOG.md000066400000000000000000000020301205417650100140660ustar00rootroot00000000000000# CHANGELOG ## v1.1.1 Bugfix release * The logging to file function crashed on unsupported systems due to immediate execution ## v1.1.0 * Custom message composer ## v1.0.0 WARNING: This upgrade is not API compatible to previous version. * Change the API to actually use JavaScript's new operator to create loggers var SysLogger = require('ain2'); var logger = new SysLogger({ port : 514, tag : 'myTag' }); * If you want to have singleton logger, use var logger = require('ain2').getInstance(); ## v0.2.1 * Support for node v0.6.0 (Yoji Shidara/darashi) ## v0.2.0 * Support for unix sockets, for the 0.4.x branch of node (Parham Michael Ossareh/ossareh) ## v0.0.3 * Explicitly fall back to original `console` object to log send failures (Mark Wubben/novemberborn) * Default hostname to machine name rather than localhost (Mark Wubben/novemberborn) * Fixes to make jslint happy (Mark Wubben/novemberborn, Patrick Huesler/phuesler) * Test server for local testing ## v0.0.2 * add support for custom host and port ain-1.1.1/LICENSE000066400000000000000000000020721205417650100132700ustar00rootroot00000000000000Copyright (c) 2010 Alexander Dorofeev Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.ain-1.1.1/index.js000066400000000000000000000217371205417650100137410ustar00rootroot00000000000000var dgram = require('dgram'); var Buffer = require('buffer').Buffer; var nodeConsole = console; var DefaultHostname = require("os").hostname(); var DefaultAddress = "127.0.0.1"; var SingletonInstance = null; var Transport = { UDP: function(message, severity) { var client = dgram.createSocket('udp4'); var self = this; var syslogMessage = this.composerFunction(message, severity); client.send(syslogMessage, 0, syslogMessage.length, this.port, this.address, function(err, bytes) { self._logError(err, bytes); client.close(); } ); }, file: (function() { var logTarget ; switch(require('os').type()) { case 'Darwin': case 'FreeBSD': logTarget = '/var/run/syslog' ; break ; case 'Linux': logTarget = '/dev/log' ; break ; default: logTarget = false ; break ; } return function(message, severity) { if (false === logTarget) { throw new Error('Unknown OS Type: ' + require('os').type()) ; } var client = dgram.createSocket('unix_dgram') ; var syslogMessage = this.composerFunction(message, severity); client.send(syslogMessage, 0, syslogMessage.length, logTarget, this._logError ); client.close() ; }; })() }; var Facility = { kern: 0, user: 1, mail: 2, daemon: 3, auth: 4, syslog: 5, lpr: 6, news: 7, uucp: 8, local0: 16, local1: 17, local2: 18, local3: 19, local4: 20, local5: 21, local6: 22, local7: 23 }; var Severity = { emerg: 0, alert: 1, crit: 2, err: 3, warn: 4, notice: 5, info: 6, debug: 7 }; // Format RegExp var formatRegExp = /%[sdj]/g; /** * Just copy from node.js console * @param f * @returns */ function format(f) { var util = require('util'), i = 0; if (typeof f !== 'string') { var objects = []; for (i = 0; i < arguments.length; i++) { objects.push(util.inspect(arguments[i])); } return objects.join(' '); } i = 1; var args = arguments; var str = String(f).replace(formatRegExp, function(x) { switch (x) { case '%s': return String(args[i++]); case '%d': return Number(args[i++]); case '%j': return JSON.stringify(args[i++]); default: return x; } }); for (var len = args.length, x = args[i]; i < len; x = args[++i]) { if (x === null || typeof x !== 'object') { str += ' ' + x; } else { str += ' ' + util.inspect(x); } } return str; } /** * Syslog logger * @constructor * @returns {SysLogger} */ function SysLogger(config) { this._times = {}; this._logError = function(err, other) { if(err){ nodeConsole.error('Cannot log message via %s:%d', this.hostname, this.port); } }.bind(this); this.set(config); return this; } /** * Get singleton instance of SysLogger. * @returns {SysLogger} */ SysLogger.getInstance = function() { if(!SingletonInstance){ SingletonInstance = new SysLogger(); } return SingletonInstance; }; /** * Init function, takes a configuration object. If a hostname is provided the transport is assumed * to be Transport.UDP * @param {Object} configuration object with the following keys: * - tag - {String} By default is __filename * - facility - {Facility|Number|String} By default is "user" * - hostname - {String} By default is require("os").hostname() * - port - {Number} Defaults to 514 * - transport - {Transport|String} Defaults to Transport.UDP */ SysLogger.prototype.set = function(config) { config = config || {} ; this.setTag(config.tag); this.setFacility(config.facility); this.setHostname(config.hostname); this.setPort(config.port); this.setMessageComposer(config.messageComposer); if (config.hostname) { this.setTransport(Transport.UDP) ; } else { this.setTransport(config.transport) ; } return this; }; SysLogger.prototype.setTransport = function(transport) { this.transport = transport || Transport.UDP; if (typeof this.transport == 'string') { this.transport = Transport[this.transport] ; } return this; }; SysLogger.prototype.setTag = function(tag) { this.tag = tag || __filename; return this; }; SysLogger.prototype.setFacility = function(facility) { this.facility = facility || Facility.user; if (typeof this.facility == 'string'){ this.facility = Facility[this.facility]; } return this; }; SysLogger.prototype.setHostname = function(hostname) { if (hostname) { this.hostname = this.address = hostname; } else { this.hostname = DefaultHostname; this.address = DefaultAddress; } return this; }; SysLogger.prototype.setPort = function(port) { this.port = port || 514; return this; }; SysLogger.prototype.setMessageComposer = function(composerFunction){ this.composerFunction = composerFunction || this.composeSyslogMessage; return this; }; /** * Send message * @param {String} message * @param {Severity} severity */ SysLogger.prototype._send = function(message, severity) { this.transport(message, severity) ; }; /** * Send formatted message to syslog * @param {String} message * @param {Number|String} severity */ SysLogger.prototype.send = function(message, severity) { severity = severity || Severity.notice; if (typeof severity == 'string'){ severity = Severity[severity]; } this._send(message, severity); }; /** * Send log message with notice severity. */ SysLogger.prototype.log = function() { this._send(format.apply(this, arguments), Severity.notice); }; /** * Send log message with info severity. */ SysLogger.prototype.info = function() { this._send(format.apply(this, arguments), Severity.info); }; /** * Send log message with warn severity. */ SysLogger.prototype.warn = function() { this._send(format.apply(this, arguments), Severity.warn); }; /** * Send log message with err severity. */ SysLogger.prototype.error = function() { this._send(format.apply(this, arguments), Severity.err); }; /** * Send log message with debug severity. */ SysLogger.prototype.debug = function() { this._send(format.apply(this, arguments), Severity.debug); }; /** * Compose syslog message */ SysLogger.prototype.composeSyslogMessage = function(message, severity) { return new Buffer('<' + (this.facility * 8 + severity) + '>' + this.getDate() + ' ' + this.hostname + ' ' + this.tag + '[' + process.pid + ']:' + message); } /** * Log object with `util.inspect` with notice severity */ SysLogger.prototype.dir = function(object) { var util = require('util'); this._send(util.inspect(object) + '\n', Severity.notice); }; SysLogger.prototype.time = function(label) { this._times[label] = Date.now(); }; SysLogger.prototype.timeEnd = function(label) { var duration = Date.now() - this._times[label]; this.log('%s: %dms', label, duration); }; SysLogger.prototype.trace = function(label) { var err = new Error(); err.name = 'Trace'; err.message = label || ''; Error.captureStackTrace(err, arguments.callee); this.error(err.stack); }; SysLogger.prototype.assert = function(expression) { if (!expression) { var arr = Array.prototype.slice.call(arguments, 1); this._send(format.apply(this, arr), Severity.err); } }; /** * Get current date in syslog format. Thanks https://github.com/kordless/lodge * @returns {String} */ SysLogger.prototype.getDate = function() { var dt = new Date(); var hours = this.leadZero(dt.getHours()); var minutes = this.leadZero(dt.getMinutes()); var seconds = this.leadZero(dt.getSeconds()); var month = dt.getMonth(); var day = dt.getDate(); if(day < 10){ day = ' ' + day; } var months = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]; return months[month] + " " + day + " " + hours + ":" + minutes + ":" + seconds; } SysLogger.prototype.leadZero = function(n) { if (n < 10) { return '0' + n; } else { return n; } } module.exports = SysLogger; ain-1.1.1/package.json000066400000000000000000000022441205417650100145520ustar00rootroot00000000000000{ "name" : "ain2", "description" : "Syslog logging for node.js. Continuation of ain", "version" : "1.1.1", "main" : "./index", "author" : "Alexander Dorofeev ", "contributors" : [ { "name" : "Alexander Dorofeev", "email" : "aka.spin@gmail.com" }, { "name" : "Patrick Huesler", "email" : "patrick.huesler@googlemail.com" }, { "name" : "Mark Wubben", "email" : "mark@novemberborn.net" }, { "name" : "Parham Michael Ossareh", "email" : "ossareh@gmail.com" }, { "name" : "Carlos Lage", "email" : "carlos.lage@livestream.com" }, { "name" : "J. Maurice", "email" : "j@wiz.biz" } ], "repository" : { "type" : "git", "url" : "http://github.com/phuesler/ain.git" }, "bugs" : { "url" : "http://github.com/phuesler/ain/issues" }, "licenses" : [ { "type": "MIT", "url": "http://github.com/phuesler/ain/master/LICENSE" } ] } ain-1.1.1/readme.md000066400000000000000000000143301205417650100140420ustar00rootroot00000000000000# ain* Brain-free [syslog](http://en.wikipedia.org/wiki/Syslog)** logging for [node.js](http://nodejs.org). *Ain* is written with full compatibility with *node.js* `console` module. It implements all `console` functions and formatting. Also *ain* supports UTF-8 (tested on Debian Testing/Sid). *Ain* can send messages by UDP to `127.0.0.1:514` or to the a unix socket; /dev/log on Linux and /var/run/syslog on Mac OS X. The unix sockets only work for the 0.4.x versions of node.js, unix_dgram sockets support has been [removed](http://groups.google.com/group/nodejs/browse_thread/thread/882ce172ec463f52/62e392bb0f32a7cb) from > 0.5.x. *In the Phoenician alphabet letter "ain" indicates eye. **All examples tested under Ubuntu `rsyslog`. On other operating systems and logging daemons settings and paths may differ. ## Installation You can install *ain* as usual - by copy the "ain" directory in your `~/.node_modules` or via *npm* npm install ain2 ## Usage Usage of *ain* is very similar to the *node.js* console. The following example demonstrates the replacement of the console: var SysLogger = require('ain2'); var console = new SysLogger(); console.log('notice: %d', Date.now()); console.info('info'); console.error('error'); After launch in `/var/log/user` you can see the following: Dec 5 06:45:26 localhost ex.js[6041]: notice: 1291513526013 Dec 5 06:45:26 localhost ex.js[6041]: info Dec 5 06:45:26 localhost ex.js[6041]: error ## Singleton logger If you want to have a singleton that points to the same object whenever you do a require, use the following: require('ain2').getInstance(); If you use this, please be beware of this: require('ain2').getInstance() === require('ain2').getInstance(); => true As opposed to: var SysLogger = require('ain2'); new SysLogger() === new SysLogger(); => false ## Changing destinations By default *ain* sets following destinations: * `TAG` - `__filename` * `Facility` - user (1) * `HOSTNAME` - localhost * `PORT` - 514 * `Transport` - UDP or Unix socket You can change them by passing in the params to the constructor or by using the `set` function. The `set` function is chainable. var SysLogger = require('ain2'); var logger = new SysLogger({tag: 'node-test-app', facility: 'daemon', hostname: 'devhost', port: 3000}); logger.warn('some warning'); ... and in `/var/log/daemon.log`: Dec 5 07:08:58 devhost node-test-app[10045]: some warning The `set` function takes one argument, a configuration object which can contain the following keys: * tag - defaults to __filename * facility - defaults to user * hostname - defaults to require('os').hostname() * port - defaults to 514 * transport - defaults to 'UDP', can also be 'file' * messageComposer - a custom function to compose syslog messages All of these are optional. If you provide a `hostname` transport is automatically set to UDP `tag` and `hostname` arguments is just *RFC 3164* `TAG` and `HOSTNAME` of your messages. `facility` is little more than just name. Refer to *Section 4.1.1* of [RFC 3164](http://www.faqs.org/rfcs/rfc3164.html) it can be: ## String Description ----------------------- 0 kern kernel messages 1 user user-level messages 2 mail mail system 3 daemon system daemons 4 auth security/authorization messages 5 syslog messages generated internally by syslog daemon 6 lpr line printer subsystem 7 news network news subsystem 8 uucp UUCP subsystem 16 local0 local use 0 17 local1 local use 1 18 local2 local use 2 19 local3 local use 3 20 local4 local use 4 21 local5 local use 5 22 local6 local use 6 23 local7 local use 7 You can set the `facility` by `String` or `Number`: logger.set({tag: 'node-test-app', facility: 3}); logger.set({tag: 'node-test-app', facility: 'daemon'}); Also you can set `TAG`, `Facility`, `HOSTNAME`, `PORT`, and `transport` separately by `setTag`, `setFacility`, `setHostname`, `setPort`, `setTransport` and `setMessageComposer` functions. All of them are chainable too. You can get all destinations by these properties: * `tag` TAG * `facility` Numerical representation of RFC 3164 facility * `hostname` HOSTNAME * `port` PORT ## Custom message composer var SysLogger = require('ain2'); var console = new SysLogger(); console.setMessageComposer(function(message, severity){ return new Buffer('<' + (this.facility * 8 + severity) + '>' + this.getDate() + ' ' + '[' + process.pid + ']:' + message); }); //The default implementation looks this: SysLogger.prototype.composeSyslogMessage = function(message, severity) { return new Buffer('<' + (this.facility * 8 + severity) + '>' + this.getDate() + ' ' + this.hostname + ' ' + this.tag + '[' + process.pid + ']:' + message); } ## Logging As noticed before *ain* implements all `console` functions. Severity level is referenced to [RFC 3164](http://www.faqs.org/rfcs/rfc3164.html): # String Description ----------------------- 0 emerg Emergency: system is unusable 1 alert Alert: action must be taken immediately 2 crit Critical: critical conditions 3 err Error: error conditions 4 warn Warning: warning conditions 5 notice Notice: normal but significant condition 6 info Informational: informational messages 7 debug Debug: debug-level messages *Ain* `console`-like functions behaviour is fully compatible to *node.js* and logs messages with different severity levels: * `log` - notice (5) * `info` - info (6) * `warn` - warn (4) * `error` - err (3) * `dir` - notice (5) * `time`, `timeEnd` - notice (5) * `trace` - err (3) * `assert` - err (3) To log a message with the desired severity level you can use the `send` function: logger.send('message', 'alert'); The `send` function takes two arguments: message and optional severity level. By default, the severity level is *notice*. ain-1.1.1/test/000077500000000000000000000000001205417650100132415ustar00rootroot00000000000000ain-1.1.1/test/integration.js000066400000000000000000000021611205417650100161220ustar00rootroot00000000000000function executeDifferentLogCalls(logger){ logger.log('log'); logger.info('info'); logger.warn('warn'); logger.error('error'); logger.debug('debug'); } function runTests(){ var Syslog = require('../index.js'); var logger = new Syslog({port : 5514}); executeDifferentLogCalls(logger); logger.setMessageComposer(function(message, severity){ return new Buffer('<' + (this.facility * 8 + severity) + '>' + this.getDate() + ' ' + '[' + process.pid + ']:' + message); }); executeDifferentLogCalls(logger); setTimeout(function(){ process.exit(); }, 500); } function setupServer(){ var dgram = require("dgram"); var server = dgram.createSocket("udp4"); var messages = []; server.on("message", function (msg, rinfo) { console.log(msg.toString()); messages.push(msg.toString()); }); server.on("listening", function () { var address = server.address(); console.log("server listening " + address.address + ":" + address.port); runTests(); }); server.bind(5514); } setupServer();