diff --git a/src/app.coffee b/src/app.coffee index eada82a0..6414948a 100644 --- a/src/app.coffee +++ b/src/app.coffee @@ -44,7 +44,7 @@ knex('config').select('value').where(key: 'uuid').then ([ uuid ]) -> .catch (error) -> console.error('Error starting apps:', error) .then -> - utils.mixpanelTrack('Start application update poll', {interval: config.appUpdatePollInterval}) + utils.mixpanelTrack('Start application update poll', {interval: config.appUpdatePollInterval}) setInterval(-> application.update() , config.appUpdatePollInterval) diff --git a/src/application.coffee b/src/application.coffee index ef944406..e7c934f0 100644 --- a/src/application.coffee +++ b/src/application.coffee @@ -5,38 +5,26 @@ knex = require './db' path = require 'path' config = require './config' dockerUtils = require './docker-utils' -PUBNUB = require 'pubnub' Promise = require 'bluebird' PlatformAPI = require 'pinejs-client-js/request' utils = require './utils' tty = require './lib/tty' +logger = require './lib/logger' {docker} = dockerUtils PLATFORM_ENDPOINT = url.resolve(config.apiEndpoint, '/ewa/') resinAPI = new PlatformAPI(PLATFORM_ENDPOINT) -pubnub = PUBNUB.init(config.pubnub) - -# Queue up any calls to publish while we wait for the uuid to return from the sqlite db -publish = do -> - publishQueue = [] - - knex('config').select('value').where(key: 'uuid').then ([ uuid ]) -> - uuid = uuid.value - channel = "device-#{uuid}-logs" - - # Redefine original function - publish = (message) -> - pubnub.publish({ channel, message }) - - # Replay queue now that we have initialised the publish function - publish(args...) for args in publishQueue - - return -> publishQueue.push(arguments) +knex('config').select('value').where(key: 'uuid').then ([ uuid ]) -> + logger.init( + dockerSocket: config.dockerSocket + pubnub: config.pubnub + channel: "device-#{uuid.value}-logs" + ) exports.logSystemEvent = logSystemEvent = (message) -> - publish("[system] " + message) + logger.log('[system] ' + message) exports.kill = kill = (app) -> logSystemEvent('Killing application ' + app.imageId) @@ -154,13 +142,7 @@ exports.start = start = (app) -> ) .then -> updateDeviceInfo(commit: app.commit) - container.attachAsync({ stream: true, stdout: true, stderr: true, tty: true }) - .then (stream) -> - es.pipeline( - stream - es.split() - es.mapSync(publish) - ) + logger.attach(app) .tap -> utils.mixpanelTrack('Application start', app.imageId) logSystemEvent('Starting application ' + app.imageId) diff --git a/src/lib/logger.coffee b/src/lib/logger.coffee new file mode 100644 index 00000000..744838fb --- /dev/null +++ b/src/lib/logger.coffee @@ -0,0 +1,48 @@ +Docker = require 'dockerode' +PUBNUB = require 'pubnub' +Promise = require 'bluebird' + +initialised = new Promise (resolve) -> + exports.init = (config) -> + resolve(config) + +dockerPromise = initialised.then (config) -> + docker = Promise.promisifyAll(new Docker(socketPath: config.dockerSocket)) + # Hack dockerode to promisify internal classes' prototypes + Promise.promisifyAll(docker.getImage().constructor.prototype) + Promise.promisifyAll(docker.getContainer().constructor.prototype) + return docker + +# Queue up any calls to publish logs whilst we wait to be initialised. +publish = do -> + publishQueue = [] + + initialised.then (config) -> + pubnub = PUBNUB.init(config.pubnub) + channel = config.channel + + # Redefine original function + publish = (message) -> + # Stop pubnub logging loads of "Missing Message" errors, as they are quite distracting + message or= ' ' + pubnub.publish({ channel, message }) + + # Replay queue now that we have initialised the publish function + publish(args...) for args in publishQueue + + return -> publishQueue.push(arguments) + +exports.log = -> + publish(arguments...) + +# Helps in blinking the LED from the given end point. +exports.attach = (app) -> + dockerPromise.then (docker) -> + docker.getContainer(app.containerId) + .attachAsync({ stream: true, stdout: true, stderr: true, tty: true }) + .then (stream) -> + es.pipeline( + stream + es.split() + es.mapSync(publish) + )