2 * webhook.js: Transport for logging to remote http endpoints ( POST / RECEIVE webhooks )
4 * (C) 2011 Marak Squires
9 var events = require('events'),
10 http = require('http'),
11 https = require('https'),
12 util = require('util'),
13 common = require('../common'),
14 Transport = require('./transport').Transport;
17 // ### function WebHook (options)
18 // #### @options {Object} Options for this instance.
19 // Constructor function for the Console transport object responsible
20 // for making arbitrary HTTP requests whenever log messages and metadata
23 var Webhook = exports.Webhook = function (options) {
24 Transport.call(this, options);
26 this.name = 'webhook';
27 this.host = options.host || 'localhost';
28 this.port = options.port || 8080;
29 this.method = options.method || 'POST';
30 this.path = options.path || '/winston-log';
34 this.auth.username = options.auth.username || '';
35 this.auth.password = options.auth.password || '';
40 this.ssl.key = options.ssl.key || null;
41 this.ssl.cert = options.ssl.cert || null;
42 this.ssl.ca = options.ssl.ca;
47 // Inherit from `winston.Transport`.
49 util.inherits(Webhook, Transport);
52 // Expose the name of this Transport on the prototype
54 Webhook.prototype.name = 'webhook';
57 // ### function log (level, msg, [meta], callback)
58 // #### @level {string} Level at which to log the message.
59 // #### @msg {string} Message to log
60 // #### @meta {Object} **Optional** Additional metadata to attach
61 // #### @callback {function} Continuation to respond to when complete.
62 // Core logging method exposed to Winston. Metadata is optional.
64 Webhook.prototype.log = function (level, msg, meta, callback) {
66 return callback(null, true);
70 message = common.clone(meta),
74 message.level = level;
75 message.message = msg;
77 // Prepare options for outgoing HTTP request
83 headers: { 'Content-Type': 'application/json' }
87 options.ca = this.ssl.ca;
88 options.key = this.ssl.key;
89 options.cert = this.ssl.cert;
93 // Encode `Authorization` header used by Basic Auth
94 options.headers['Authorization'] = 'Basic ' + new Buffer(
95 this.auth.username + ':' + this.auth.password, 'utf8'
99 // Perform HTTP logging request
100 req = (self.ssl ? https : http).request(options, function (res) {
102 // No callback on request, fire and forget about the response
107 req.on('error', function (err) {
109 // Propagate the `error` back up to the `Logger` that this
110 // instance belongs to.
112 self.emit('error', err);
116 // Write logging event to the outgoing request body
118 // jsonMessage is currently conforming to JSON-RPC v1.0,
119 // but without the unique id since there is no anticipated response
120 // see: http://en.wikipedia.org/wiki/JSON-RPC
122 req.write(JSON.stringify({
125 timestamp: new Date(),
134 // Always return true, regardless of any errors
135 callback(null, true);