├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── index.js ├── package.json └── test └── test.js /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | .DS_Store* 3 | *.log 4 | *.gz 5 | 6 | node_modules 7 | coverage 8 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | node_js: 2 | - "0.11" 3 | language: node_js 4 | script: "npm run-script test-travis" 5 | after_script: "npm install coveralls@2 && cat ./coverage/lcov.info | coveralls" 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2015 Jonathan Ong me@jongleberry.com 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # koa-trace-influxdb 3 | 4 | [![NPM version][npm-image]][npm-url] 5 | [![Build status][travis-image]][travis-url] 6 | [![Test coverage][coveralls-image]][coveralls-url] 7 | [![Dependency Status][david-image]][david-url] 8 | [![License][license-image]][license-url] 9 | [![Downloads][downloads-image]][downloads-url] 10 | [![Gittip][gittip-image]][gittip-url] 11 | 12 | Tracing for [koa-trace](https://github.com/koajs/trace) using [influxdb-udp](https://github.com/jonathanong/node-influxdb-udp). 13 | 14 | ## Usage 15 | 16 | ```js 17 | var app = koa(); 18 | require('koa-trace')(app); 19 | 20 | var traceInflux = require('koa-trace-influxdb'); 21 | app.instrument(traceInflux({ 22 | port: 4444, 23 | host: '127.0.0.1' 24 | })); 25 | 26 | app.use(function* (next) { 27 | // set an ID for every request. 28 | // optionally, make this a request UUID 29 | this.id = '1234'; 30 | 31 | // optionally set properties to add to all traces 32 | this.traces = { 33 | user_id: this.session.user_id.toString('hex') 34 | }; 35 | 36 | // trace something 37 | this.trace('start') 38 | }) 39 | ``` 40 | 41 | This will create a time series called `trace.start`. 42 | Thus, it tracks each event as a separate series. 43 | You probably want to track the elapsed time. 44 | 45 | ```js 46 | app.use(function* (next) { 47 | var start = Date.now(); 48 | 49 | yield* next; 50 | 51 | this.trace('response-time', { 52 | elapsed: Date.now() - start 53 | }); 54 | }); 55 | ``` 56 | 57 | You may want to build your own helper for this. 58 | 59 | ## Options 60 | 61 | - `host` 62 | - `port` 63 | - `prefix` - prefix to add to all the series, defaulting to `trace.`. 64 | If you don't want any prefixes, set it as `''`. 65 | 66 | ## Limitations 67 | 68 | - The trace arguments must only be a single object, if anything at all. 69 | - UDP is used underneath, so you may lose events. 70 | There is no error reporting for logging these. 71 | 72 | [gitter-image]: https://badges.gitter.im/koajs/trace-influxdb.png 73 | [gitter-url]: https://gitter.im/koajs/trace-influxdb 74 | [npm-image]: https://img.shields.io/npm/v/koa-trace-influxdb.svg?style=flat-square 75 | [npm-url]: https://npmjs.org/package/koa-trace-influxdb 76 | [github-tag]: http://img.shields.io/github/tag/koajs/trace-influxdb.svg?style=flat-square 77 | [github-url]: https://github.com/koajs/trace-influxdb/tags 78 | [travis-image]: https://img.shields.io/travis/koajs/trace-influxdb.svg?style=flat-square 79 | [travis-url]: https://travis-ci.org/koajs/trace-influxdb 80 | [coveralls-image]: https://img.shields.io/coveralls/koajs/trace-influxdb.svg?style=flat-square 81 | [coveralls-url]: https://coveralls.io/r/koajs/trace-influxdb 82 | [david-image]: http://img.shields.io/david/koajs/trace-influxdb.svg?style=flat-square 83 | [david-url]: https://david-dm.org/koajs/trace-influxdb 84 | [license-image]: http://img.shields.io/npm/l/koa-trace-influxdb.svg?style=flat-square 85 | [license-url]: LICENSE 86 | [downloads-image]: http://img.shields.io/npm/dm/koa-trace-influxdb.svg?style=flat-square 87 | [downloads-url]: https://npmjs.org/package/koa-trace-influxdb 88 | [gittip-image]: https://img.shields.io/gratipay/jonathanong.svg?style=flat-square 89 | [gittip-url]: https://gratipay.com/jonathanong/ 90 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 2 | var Influx = require('influxdb-udp') 3 | 4 | module.exports = function (options) { 5 | options = options || {} 6 | var influx = Influx(options) 7 | 8 | // prefix for the series 9 | // note: you can have '' as the prefix, i.e. no prefix 10 | var prefix = typeof options.prefix === 'string' 11 | ? options.prefix 12 | : 'trace.' 13 | if (prefix && !/\.$/.test(prefix)) prefix += '.' 14 | 15 | return function (context, event, date, args) { 16 | var obj = { 17 | time: Date.now(), 18 | } 19 | 20 | var id = context.id 21 | if (Buffer.isBuffer(id)) id = id.toString('base64') 22 | if (id) obj.id = id 23 | 24 | if (context.traces) { 25 | Object.keys(context.traces).forEach(function (key) { 26 | obj[key] = context.traces[key] 27 | }) 28 | } 29 | 30 | var arg = args[0] 31 | if (typeof arg === 'object' && !Array.isArray(arg)) { 32 | Object.keys(arg).forEach(function (key) { 33 | obj[key] = arg[key] 34 | }) 35 | } 36 | 37 | influx.write(prefix + event, obj) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "koa-trace-influxdb", 3 | "description": "", 4 | "version": "1.0.0", 5 | "author": "Jonathan Ong (http://jongleberry.com)", 6 | "license": "MIT", 7 | "repository": "koajs/trace-influxdb", 8 | "dependencies": { 9 | "influxdb-udp": "^1.0.0" 10 | }, 11 | "devDependencies": { 12 | "istanbul-harmony": "0", 13 | "koa": "^0.14.0", 14 | "koa-trace": "^1.0.0", 15 | "mocha": "2", 16 | "supertest": "^0.15.0" 17 | }, 18 | "scripts": { 19 | "test": "mocha --harmony-generators --reporter spec", 20 | "test-cov": "node --harmony-generators node_modules/.bin/istanbul cover ./node_modules/.bin/_mocha -- --reporter dot", 21 | "test-travis": "node --harmony-generators node_modules/.bin/istanbul cover ./node_modules/.bin/_mocha --report lcovonly -- --reporter dot" 22 | }, 23 | "keywords": [ 24 | "trace", 25 | "koa", 26 | "influx", 27 | "influxdb" 28 | ], 29 | "files": [ 30 | "index.js" 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | 2 | var request = require('supertest') 3 | var assert = require('assert') 4 | var koa = require('koa') 5 | 6 | var app = koa() 7 | require('koa-trace')(app) 8 | app.instrument(require('..')()) 9 | 10 | app.use(function* (next) { 11 | this.id = '1234' 12 | yield* next 13 | }) 14 | 15 | it('should create an object', function (done) { 16 | app.use(function* (next) { 17 | if (this.path !== '/1') return yield* next 18 | 19 | this.status = 204 20 | this.trace('asdf'); 21 | }) 22 | 23 | request(app.listen()) 24 | .get('/1') 25 | .expect(204, done) 26 | }) 27 | 28 | it('should create use the argument', function (done) { 29 | app.use(function* (next) { 30 | if (this.path !== '/2') return yield* next 31 | 32 | this.status = 204 33 | this.trace('asdf', { 34 | c: 1 35 | }); 36 | }) 37 | 38 | request(app.listen()) 39 | .get('/2') 40 | .expect(204, done) 41 | }) 42 | 43 | it('should create use the trace object', function (done) { 44 | app.use(function* (next) { 45 | if (this.path !== '/3') return yield* next 46 | 47 | this.status = 204 48 | this.traces = { 49 | a: 1 50 | } 51 | this.trace('asdf') 52 | }) 53 | 54 | request(app.listen()) 55 | .get('/3') 56 | .expect(204, done) 57 | }) 58 | 59 | it('should create use both the argument and the trace object', function (done) { 60 | app.use(function* (next) { 61 | if (this.path !== '/4') return yield* next 62 | 63 | this.status = 204 64 | this.traces = { 65 | a: 1 66 | } 67 | this.trace('asdf', { 68 | c: 1 69 | }) 70 | }) 71 | 72 | request(app.listen()) 73 | .get('/4') 74 | .expect(204, done) 75 | }) 76 | --------------------------------------------------------------------------------