Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
kilianc committed May 29, 2015
2 parents 38eefe4 + b1ce0ba commit 48134eb
Show file tree
Hide file tree
Showing 63 changed files with 2,723 additions and 683 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
app/css/*
app/*.js
dist
3 changes: 3 additions & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
app
gulpfile.js
wercker.yml
81 changes: 58 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,27 @@
# `rtail(1)` (DO NOT USE IT YET)
[![Gitter](https://badges.gitter.im/Join Chat.svg)](https://gitter.im/kilianc/rtail?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
# `rtail(1)`

Stupid simple UNIX style stream broadcast over UDP in your browser.
[![Wercker CI](https://img.shields.io/wercker/ci/556547b7be632a8c751c857d.svg?style=flat-square)](https://app.wercker.com/project/bykey/54b073dac5b9156509c26031c78c98d4)
[![Coveralls](https://img.shields.io/coveralls/kilianc/rtail.svg?style=flat-square)](https://coveralls.io/r/kilianc/rtail)
[![NPM version](https://img.shields.io/npm/v/rtail.svg?style=flat-square)](https://www.npmjs.com/package/rtail)
[![NPM downloads](https://img.shields.io/npm/dm/rtail.svg?style=flat-square)](https://www.npmjs.com/package/rtail)
[![GitHub Stars](https://img.shields.io/github/stars/kilianc/rtail.svg?style=flat-square)](https://github.com/kilianc/rtail)
[![License](https://img.shields.io/npm/l/rtail.svg?style=flat-square)](https://www.npmjs.com/package/rtail)
[![Gitter](https://img.shields.io/badge/≡_gitter-join_chat_➝-04cd7e.svg?style=flat-square)](https://gitter.im/kilianc/rtail?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)

`rtail` is a command line utility that grabs every line in `stdin` and broadcast it over **UDP**. That's it, nothing fancy, nothing complicated. You can tail your log files, your app logs or whatever you wish to pipe in `rtail` to a `rtail-server` and see multiple streams in the browser, realtime.
## Pipe your terminal output to the browser in seconds, using UNIX pipes.

`rtail` is a command line utility that grabs every line in `stdin` and broadcast it over **UDP**. That's it, nothing fancy, nothing complicated. You can tail your log files, your app output or whatever you wish to pipe, in `rtail` to a `rtail-server` and see multiple streams in the browser, realtime.

## Installation

$ npm install -g rtail

## Web app

![](https://s3.amazonaws.com/rtail/github/dark.png)

![](https://s3.amazonaws.com/rtail/github/light.png)

## Rationale

If you develop software for work and you deploy your code on remote servers using multiple environments, or simply have multiple projects, you know that to monitor realtime your logs **you need to `ssh` to every single machine running your code**.
Expand Down Expand Up @@ -55,19 +68,21 @@ For fun and debugging
Usage: cmd | rtail --host [string] --port [num] [--mute] [--id [string]]

Examples:
server | rtail --host 127.0.0.1 > server.log broadcast to localhost + file
server | rtail --port 43567 custom port
server | rtail --mute only remote
server | rtail --id api.domain.com name the log stream
server | rtail --host 127.0.0.1 > server.log Broadcast to localhost + file
server | rtail --port 43567 Custom port
server | rtail --mute Only remote
server | rtail --id api.domain.com Name the log stream
server | rtail --not-tty Strips ANSI colors


Options:
--mute, -m don't pipe stdin with stdout
--host the recipient server host [default: "127.0.0.1"]
--port, -p the recipient server port [default: 9999]
--id, --name, -n the log stream id [default: uuid()]
--help, -h Show help
--version, -v Show version number
--mute, -m Don't pipe stdin with stdout
--host The recipient server host [default: "127.0.0.1"]
--port, -p The recipient server port [default: 9999]
--id, --name The log stream id [default: moniker()]
--not-tty Strips ansi colors
--help, -h Show help
--version, -v Show version number

## `rtail-server(1)`

Expand All @@ -81,28 +96,42 @@ With default values

$ rtail-server

Stay up to date!

$ rtail-server --web-version stable

With custom ports

$ rtail-server --web-port 8080 --udp-port 9090

With debugging on

$ DEBUG=rtail:* rtail-server

With serving always latest stable webapp

$ DEBUG=rtail:* rtail-server --web-version stable

Open your browser and start tailing logs!

## Params

$ rtail-server
Usage: rtail-server [--udp-host [string] --udp-port [num] --web-host [string] --web-port [num]]
$ rtail-server -h
Usage: rtail-server [--udp-host [string] --udp-port [num] --web-host [string] --web-port [num] --web-version [stable,unstable,<version>]]

Examples:
rtail-server --web-port 8080 custom http port
rtail-server --udp-port 8080 custom udp port
rtail-server --web-port 8080 Use custom http port
rtail-server --udp-port 8080 Use custom udp port
rtail-server --web-version stable Always uses latest stable webapp
rtail-server --web-version 0.1.3 Use webapp v0.1.3


Options:
--udp-host, --uh the listening udp hostname [default: "localhost"]
--udp-port, --up the listening udp port [default: 9999]
--web-host, --wh the listening http hostname [default: "localhost"]
--web-port, --wp the listening http port [default: 8888]
--udp-host, --uh The listening udp hostname [default: "127.0.0.1"]
--udp-port, --up The listening udp port [default: 9999]
--web-host, --wh The listening http hostname [default: "127.0.0.1"]
--web-port, --wp The listening http port [default: 8888]
--web-version Define web app version to serve
--help, -h Show help
--version, -v Show version number

Expand All @@ -127,11 +156,17 @@ The test suite is written on top of [visionmedia/mocha](http://visionmedia.githu

$ npm test

## Contributors

* [Kilian Ciuffolo](https://github.com/kilianc)
* [Luca Orio](https://www.behance.net/lucaorio)
* [Sandaruwan Silva](https://github.com/s-silva)

## License

_This software is released under the MIT license cited below_.

Copyright (c) 2014 Kilian Ciuffolo, [email protected]. All Rights Reserved.
Copyright (c) 2015 Kilian Ciuffolo, [email protected]. All Rights Reserved.

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
Expand Down
184 changes: 184 additions & 0 deletions app/app.ejs
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
/**
* Main JS controller for webapp
*/

angular
.module('app', [
'ngAnimate',
'angularMoment',
'LocalForageModule',
'rt.popup'
])
.controller('MainController', function MainController($scope, $injector) {
var $sce = $injector.get('$sce')
var $moment = $injector.get('moment')
var $localForage = $injector.get('$localForage')
var $window = $injector.get('$window')
var $streamLines = $('.stream-lines')
var BUFFER_SIZE = 100
var ctrl = this

ctrl.paused = false
ctrl.version = '<%= version %>'
ctrl.lines = []

/**
* Socket stuff
*/

ctrl.socket = io(document.location.origin, { path: document.location.pathname + 'socket.io' })

ctrl.socket.on('streams', function (streams) {
ctrl.streams = streams
$scope.$apply()
})

ctrl.socket.on('backlog', function (lines) {
if (!lines) return
ctrl.lines = lines.map(formatLine)
$scope.$apply()
updateScroll()
console.info('%s: backlog received %d', ctrl.activeStream, lines.length)
})

ctrl.socket.on('line', function (line) {
ctrl.lines.push(formatLine(line))

if (ctrl.lines.length > BUFFER_SIZE) {
ctrl.lines.length >= 100 && ctrl.lines.shift()
}

$scope.$apply()
updateScroll()
})

ctrl.selectStream = function selectStream(stream) {
ctrl.activeStream = stream
ctrl.socket.emit('select stream', stream)
ctrl.resume()
$localForage.setItem('activeStream', stream)
}

ctrl.isSelected = function isSelected(stream) {
return ctrl.activeStream === stream
}

function updateScroll() {
var where = ctrl.streamDirection ? $streamLines[0].scrollHeight : 0
$streamLines.scrollTop(where)
}

function formatLine(line) {
if (!line.content) {
// handle empty line
line.html = $sce.trustAsHtml('')
} else if ('object' === line.type) {
// for object just format JSON
line.html = hljs.highlight('json', JSON.stringify(line.content, null, ' ')).value
line.html = $sce.trustAsHtml('<pre>' + line.html + '</pre>')
} else {
// for log lines use ansi format
line.html = ansi_up.ansi_to_html(line.content, { use_classes: true })
line.html = $sce.trustAsHtml(line.html)
}

return line
}

ctrl.resume = function resume() {
if (!ctrl.paused) return
ctrl.paused = false
ctrl.socket.emit('select stream', ctrl.activeStream)
$streamLines.on('mousewheel', ctrl.pause)
}

ctrl.pause = function pause() {
if (ctrl.paused) return
ctrl.paused = true
ctrl.socket.emit('select stream')
$streamLines.off('mousewheel', ctrl.pause)
$scope.$apply()
}

$streamLines.on('mousewheel', ctrl.pause)

/**
* Settings and preferences
*/

ctrl.toggleFavorite = function toggleFavorite(stream) {
if (ctrl.favorites[stream]) {
delete ctrl.favorites[stream]
} else {
ctrl.favorites[stream] = true
}

$localForage.setItem('favorites', ctrl.favorites)
}

ctrl.setTheme = function setTheme(theme) {
ctrl.theme = theme
$localForage.setItem('theme', theme)
}

ctrl.setFontFamily = function setFontFamily(fontFamily) {
ctrl.fontFamily = fontFamily
$localForage.setItem('fontFamily', fontFamily)
}

ctrl.incFontSize = function incFontSize(fontSize) {
ctrl.fontSize = Math.min(7, ctrl.fontSize + 1)
$localForage.setItem('fontSize', ctrl.fontSize)
}

ctrl.resetFontSize = function resetFontSize() {
ctrl.fontSize = 4
$localForage.setItem('fontSize', ctrl.fontSize)
}

ctrl.decFontSize = function decFontSize(fontSize) {
ctrl.fontSize = Math.max(1, ctrl.fontSize - 1)
$localForage.setItem('fontSize', fontSize)
}

ctrl.setStreamDirection = function setStreamDirection(streamDirection) {
ctrl.streamDirection = streamDirection
$localForage.setItem('streamDirection', streamDirection)
}

/**
* Load storage in memory and boot
*/

$localForage.getItem('theme').then(function (theme) {
ctrl.theme = theme || 'dark'
})

$localForage.getItem('fontFamily').then(function (fontFamily) {
ctrl.fontFamily = fontFamily || 1
})

$localForage.getItem('fontSize').then(function (fontSize) {
ctrl.fontSize = fontSize || 4
})

$localForage.getItem('favorites').then(function (favorites) {
ctrl.favorites = favorites || {}
})

$localForage.getItem('activeStream').then(function (activeStream) {
if (!activeStream) return
console.info('%s: restoring session', activeStream)
ctrl.selectStream(activeStream)
})

$localForage.getItem('streamDirection').then(function (streamDirection) {
ctrl.streamDirection = undefined === streamDirection ? true : streamDirection
})

/**
* Tell UI we're ready to roll
*/

ctrl.loaded = true
})
16 changes: 16 additions & 0 deletions app/images/common/btn-fav-off.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 16 additions & 0 deletions app/images/common/btn-fav-on.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/images/common/favicon-16x16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/images/common/favicon-32x32.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/images/common/favicon-96x96.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 16 additions & 0 deletions app/images/common/icn-filter.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 48134eb

Please sign in to comment.