Skip to content

Instantly share code, notes, and snippets.

@JackDanger
Created June 22, 2010 00:28
Show Gist options
  • Save JackDanger/447748 to your computer and use it in GitHub Desktop.
Save JackDanger/447748 to your computer and use it in GitHub Desktop.
forgetful.js
// Forgetful.js is what I use on SSDs to prevent disk wear.
// Because each SSD sector can only be written a set # of times
// it's important not to write huge log files for no reason.
// So my test logs (and some others) are all outputted to this
// node.js instance which keeps track of the throughput
// in simply-named channels.
//
// To use this in, e.g., Rails, put this in environments/test.rb:
//
// class NamedChannelSocket < TCPSocket
// def write(message)
// # anything subscribed to 'test' will receive these messages
// super "#{Rails.env}|#{message}"
// end
// end
// config.logger = Logger.new(NamedLogSocket.new 'localhost', '1050')
//
// And read it in your terminal like so:
// (replace 'test' with whatever channel you want to subscribe to)
//
// echo 'test' | netcat localhost 9050
//
var net = require('net'),
system = require('sys'),
channels = {},
loggerPort = 1050,
readerPort = 9050
net.createServer(function (reader) {
reader.setEncoding('utf8')
reader.addListener('connect', function () {
system.puts( 'client connected' )
})
reader.addListener('data', function (line) {
if ( reader.channelNames && [] != reader.channelNames)
return
var channelNames = line.toString().split( ' ' )
reader.channelNames = channelNames
reader.write( "You are now listening to the "+channelNames.length+" channels: "+channelNames )
for ( var i = 0, max = channelNames.length; i < max; i++ ) {
var name = channelNames[i]
if ( !channels[name] )
channels[name] = []
channels[name].push( reader )
}
})
reader.addListener('end', function () {
for ( var i = 0, max = reader.channels.length; i < max; i++ ) {
var channel = channels[reader.channelNames[i]]
for ( var j = 0; j < channel.length; j++)
if ( channel[j] == reader )
delete channel[j]
}
reader.end()
})
reader.addListener('unhandledException', function (error) {
system.puts( 'unhandledException:' + system.inspect(error) )
})
reader.addListener('error', function (error) {
if('ECONNRESET, Connection reset by peer' == error.message)
system.puts( 'client disconnected')
else
system.puts( 'error:' + system.inspect(error) )
})
}).listen(readerPort, '127.0.0.1')
net.createServer(function (logger) {
logger.setEncoding('utf8')
logger.addListener('data', function (data) {
// var data = JSON.parse( data )
// ^ fails on colored text markup sent as utf-8
// using stupid |-delimited non-JSON format.
var parts = data.split( '|' )
var channel = channels[parts.shift()]
var message = parts.join( '|' )
if (!channel)
return
for ( var i = 0, max = channel.length; i < max; i++ )
channel[i].write( message )
})
logger.addListener('end', function () { logger.end() })
logger.addListener('unhandledException', function (error) {
system.puts( 'server::error::' + system.inspect(error) )
})
}).listen(loggerPort, '127.0.0.1')
# add this to your Rake load path to start forgetful in the current terminal window
#
# run with:
# rake forgetful
#
js = 'lib/forgetful.js'
desc "Start the Forgetful.js server logging to memory"
task 'forgetful:start' do
system "(node #{js} &) && sleep 1"
end
task :forgetful => 'forgetful:start' do
exec 'echo test forgetful | netcat localhost 9050'
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment