Permalink
Browse files

Initial commit

  • Loading branch information...
0 parents commit 1592e8221580e14091ab18913ad4e8b5eed0324f @tj committed Mar 27, 2012
Showing with 706 additions and 0 deletions.
  1. +3 −0 .gitignore
  2. +4 −0 .npmignore
  3. +5 −0 History.md
  4. +8 −0 Makefile
  5. +29 −0 Readme.md
  6. +65 −0 bin/jog
  7. +48 −0 examples/graph.js
  8. +31 −0 examples/json-select.js
  9. +35 −0 examples/map-reduce.js
  10. +27 −0 examples/video.js
  11. +2 −0 index.js
  12. +142 −0 lib/jog.js
  13. +93 −0 lib/stores/FileStore.js
  14. +85 −0 lib/stores/RedisStore.js
  15. +11 −0 package.json
  16. +6 −0 test/FileStore.js
  17. +6 −0 test/RedisStore.js
  18. +59 −0 test/jog.js
  19. +47 −0 test/shared/Store.js
@@ -0,0 +1,3 @@
+.DS_Store
+node_modules
+*.sock
@@ -0,0 +1,4 @@
+support
+test
+examples
+*.sock
@@ -0,0 +1,5 @@
+
+0.0.1 / 2010-01-03
+==================
+
+ * Initial release
@@ -0,0 +1,8 @@
+
+test:
+ @./node_modules/.bin/mocha \
+ --timeout 500 \
+ --reporter dot \
+ --require should
+
+.PHONY: test
@@ -0,0 +1,29 @@
+
+# jog
+
+ JSON logging & reporting inspired by Loggly.
+
+## License
+
+(The MIT License)
+
+Copyright (c) 2012 LearnBoost <tj@learnboost.com>
+
+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.
65 bin/jog
@@ -0,0 +1,65 @@
+#!/usr/bin/env node
+
+var program = require('commander')
+ , jog = require('..');
+
+program
+ .version(jog.version)
+ .option('-q, --query <str>', 'query with the given string')
+ .option('-F, --file <path>', 'load from the given <path>')
+ .option('-R, --redis', 'load from redis store')
+ .option('-s, --select <fn>', 'use the given <fn> for filtering')
+ .option('-m, --map <fn>', 'use the given <fn> for mapping')
+ .parse(process.argv);
+
+// determine store
+
+var store = program.file
+ ? new jog.FileStore(program.file)
+ : program.redis
+ ? new jog.RedisStore
+ : null;
+
+// no store
+
+if (!store) throw new Error('store required, use --file or --redis');
+
+// setup
+
+var log = jog(store)
+ , stream = log.stream()
+ , results = []
+ , select
+ , map
+ , prop;
+
+// --select
+
+if (program.select) select = new Function('_', 'return ' + program.select);
+
+// --map
+
+if (program.map) map = new Function('_', 'return ' + program.map);
+
+// stream data
+
+stream.on('data', function(line){
+ var ret;
+
+ if (select) {
+ if (select(line)) ret = line;
+ } else {
+ ret = line;
+ }
+
+ if (undefined !== ret) {
+ if (map) ret = map(ret);
+ results.push(ret);
+ }
+});
+
+// output results
+
+stream.on('end', function(){
+ console.log(results);
+});
@@ -0,0 +1,48 @@
+
+var Jog = require('..')
+ , log = new Jog(new Jog.FileStore('/tmp/graph'))
+ , Canvas = require('canvas')
+ , canvas = new Canvas(300, 300)
+ , ctx = canvas.getContext('2d')
+ , fs = require('fs');
+
+// regular logs
+var n = Math.random() * 100 | 0;
+while (n--) log.info('something happened');
+
+// error logs
+log.error('something broke');
+log.error('something broke');
+log.error('something broke');
+
+// graph log levels
+
+var stream = log.stream();
+var info = 0;
+var error = 0;
+
+stream.on('data', function(obj){
+ if ('error' == obj.level) ++error;
+ if ('info' == obj.level) ++info;
+});
+
+stream.on('end', function(){
+ var w = 300, h = 300;
+ var max = Math.max(info, error);
+
+ ctx.fillStyle = 'white';
+ ctx.fillRect(0, 0, w, h);
+ ctx.globalAlpha = .5;
+ ctx.fillStyle = 'black';
+
+ // info
+ ctx.fillRect(5, 0, w / 2 - 10, h);
+
+ // error
+ ctx.fillStyle = 'red';
+ var height = h * (error / max);
+ ctx.fillRect(w / 2, h - height, w / 2 - 5, height);
+
+ fs.writeFile('graph.png', canvas.toBuffer());
+ console.log('saved ./graph.png');
+});
@@ -0,0 +1,31 @@
+
+var Jog = require('..')
+ , select = require('JSONSelect')
+ , log = new Jog(new Jog.FileStore('/tmp/json-select'));
+
+var users = [];
+
+var selector = select.compile('.user .age:expr(x > 2)');
+
+users.push({ name: 'manny', age: 2, species: 'cat' });
+users.push({ name: 'tobi', age: 2, species: 'ferret', cool: true });
+users.push({ name: 'loki', age: 1, species: 'ferret', fat: true });
+users.push({ name: 'jane', age: 5, species: 'ferret', bitchy: true });
+
+// generate some video logs
+
+users.forEach(function(user){
+ log.info('rendering video', { user: user });
+ log.info('compiling video', { user: user });
+ log.info('uploading video', { user: user, timestamp: Date.now() + 60000 });
+});
+
+// grep data for old animals
+
+var stream = log.stream();
+
+stream.on('data', function(obj){
+ if (selector.match(obj).length) {
+ console.log(' %s : %s : %s', obj.level, obj.user.name, obj.msg);
+ }
+});
@@ -0,0 +1,35 @@
+
+var Jog = require('..')
+ , log = new Jog(new Jog.FileStore('/tmp/map-reduce'));
+
+var users = [];
+
+users.push({ name: 'manny', age: 2, species: 'cat' });
+users.push({ name: 'tobi', age: 2, species: 'ferret', cool: true });
+users.push({ name: 'loki', age: 1, species: 'ferret', fat: true });
+users.push({ name: 'jane', age: 5, species: 'ferret', bitchy: true });
+
+// generate some video logs
+
+users.forEach(function(user){
+ log.info('rendering video', { user: user });
+ log.info('compiling video', { user: user });
+ log.info('uploading video', { user: user, timestamp: Date.now() + 60000 });
+});
+
+// map/reduce videos uploaded by user species
+
+var stream = log.stream();
+var res = {};
+
+stream.on('data', function(obj){
+ if ('uploading video' != obj.msg) return;
+ res[obj.user.species] = res[obj.user.species] || 0;
+ res[obj.user.species]++;
+});
+
+stream.on('end', function(){
+ for (var species in res) {
+ console.log(' %s : %s', species, res[species]);
+ }
+});
@@ -0,0 +1,27 @@
+
+var Jog = require('..')
+ , log = new Jog(new Jog.FileStore('/tmp/jog'));
+
+var users = ['manny', 'tobi', 'loki'];
+
+// generate some video logs
+
+users.forEach(function(user){
+ log.info('rendering video', { user: user, duration: 1000 });
+ log.info('compiling video', { user: user, duration: 2000 });
+ log.info('uploading video', { user: user, duration: 1200, timestamp: Date.now() + 60000 });
+});
+
+// grep data for tobi
+
+var stream = log.stream()
+ , ms = 0;
+
+stream.on('data', function(obj){
+ if (obj.user != 'tobi') return;
+ ms += obj.duration;
+});
+
+stream.on('end', function(){
+ console.log('took %ds to process tobi\'s data', ms / 1000);
+});
@@ -0,0 +1,2 @@
+
+module.exports = require('./lib/jog');
Oops, something went wrong.

0 comments on commit 1592e82

Please sign in to comment.