{ "_args": [ [ { "raw": "logfmt@^1.2.0", "scope": null, "escapedName": "logfmt", "name": "logfmt", "rawSpec": "^1.2.0", "spec": ">=1.2.0 <2.0.0", "type": "range" }, "/Volumes/2009-SSD/GT2/GT2-iOS/node_modules/@expo/ngrok" ] ], "_from": "logfmt@>=1.2.0 <2.0.0", "_id": "logfmt@1.2.0", "_inCache": true, "_location": "/logfmt", "_npmUser": { "name": "csquared", "email": "christopher.continanza@gmail.com" }, "_npmVersion": "1.4.3", "_phantomChildren": { "through": "2.3.8" }, "_requested": { "raw": "logfmt@^1.2.0", "scope": null, "escapedName": "logfmt", "name": "logfmt", "rawSpec": "^1.2.0", "spec": ">=1.2.0 <2.0.0", "type": "range" }, "_requiredBy": [ "/@expo/ngrok" ], "_resolved": "https://registry.npmjs.org/logfmt/-/logfmt-1.2.0.tgz", "_shasum": "1ccc067c1cfe65f3ecf5856c09d2654f69203572", "_shrinkwrap": null, "_spec": "logfmt@^1.2.0", "_where": "/Volumes/2009-SSD/GT2/GT2-iOS/node_modules/@expo/ngrok", "author": { "name": "csquared" }, "bin": { "logfmt": "./bin/logfmt" }, "bugs": { "url": "https://github.com/csquared/node-logfmt/issues" }, "dependencies": { "lodash": "~2.4.1", "split": "0.2.x", "through": "2.3.x" }, "description": "key=value logger and parser", "devDependencies": { "express": "3.3.x", "mocha": "*", "restify": "*" }, "directories": {}, "dist": { "shasum": "1ccc067c1cfe65f3ecf5856c09d2654f69203572", "tarball": "https://registry.npmjs.org/logfmt/-/logfmt-1.2.0.tgz" }, "homepage": "https://github.com/csquared/node-logfmt#readme", "keywords": [ "log", "parser", "logfmt" ], "license": "MIT", "main": "logfmt.js", "maintainers": [ { "name": "csquared", "email": "christopher.continanza@gmail.com" } ], "name": "logfmt", "optionalDependencies": {}, "readme": "# node-logfmt\n\n[![Build Status](https://travis-ci.org/csquared/node-logfmt.png)](https://travis-ci.org/csquared/node-logfmt)\n\n\n\"logfmt\" is the name for a [key value logging convention](https://github.com/kr/logfmt) we've adopted at Heroku.\n\nThis library is for both converting lines in logfmt format to objects and\nfor logging objects to a stream in logfmt format.\n\nIt provides a logfmt parser, logfmt stringifier, a logging facility,\nand both streaming and non-streaming body parsers for express and restify.\n\nYou should use this library if you're trying to write structured logs or\nif you're consuming them (especially if you're writing a logplex drain).\n\n## install\n\n npm install logfmt\n\n# use\n\n## node.js\n\nThe `logfmt` module is a singleton that works directly from require.\n\n```javascript\nvar logfmt = require('logfmt');\n\nlogfmt.stringify({foo: 'bar'});\n// 'foo=bar'\n\nlogfmt.parse('foo=bar');\n// {foo: 'bar'}\n```\n\nIt is also a constructor function, so you can use `new logfmt` to create\na new `logfmt` that you can configure differently.\n\n```javascript\nvar logfmt2 = new logfmt;\n\n// replace our stringify with JSON's\nlogfmt2.stringify = JSON.stringify\n\n// now we log JSON!\nlogfmt2.log({foo: 'bar'})\n// {\"foo\":\"bar\"}\n\n// and the original logfmt is untouched\nlogfmt.log({foo: 'bar'})\n// foo=bar\n```\n\n## command line\n\n### logfmt\n\naccepts lines on STDIN and converts them to json\n\n\n > echo \"foo=bar a=14 baz=\\\"hello kitty\\\" cool%story=bro f %^asdf\" | logfmt\n { \"foo\": \"bar\", \"a\": 14, \"baz\": \"hello kitty\", \"cool%story\": \"bro\", \"f\": true, \"%^asdf\": true }\n\n### logfmt -r (reverse)\n\naccepts JSON on STDIN and converts them to logfmt\n\n > echo '{ \"foo\": \"bar\", \"a\": 14, \"baz\": \"hello kitty\", \\\n \"cool%story\": \"bro\", \"f\": true, \"%^asdf\": true }' | logfmt -r\n foo=bar a=14 baz=\"hello kitty\" cool%story=bro f=true %^asdf=true\n\nround trips for free!\n\n > echo \"foo=bar a=14 baz=\\\"hello kitty\\\" cool%story=bro f %^asdf\" | logfmt | logfmt -r | logfmt\n { \"foo\": \"bar\", \"a\": 14, \"baz\": \"hello kitty\", \"cool%story\": \"bro\", \"f\": true, \"%^asdf\": true }\n\n\n# API\n\n## stringifying\n\nSerialize an object to logfmt format\n\n### `logfmt.stringify(object)`\n\nSerializes a single object.\n\n```javascript\nlogfmt.stringify({foo: \"bar\", a: 14, baz: 'hello kitty'})\n//> 'foo=bar a=14 baz=\"hello kitty\"'\n```\n\n## parsing\n\nParse a line in logfmt format\n\n### `logfmt.parse(string)`\n\n```javascript\nlogfmt.parse(\"foo=bar a=14 baz=\\\"hello kitty\\\" cool%story=bro f %^asdf code=H12\")\n//> { \"foo\": \"bar\", \"a\": '14', \"baz\": \"hello kitty\", \"cool%story\": \"bro\", \"f\": true, \"%^asdf\": true, \"code\" : \"H12\" }\n```\n\nThe only conversions are from the strings `true` and `false` to their proper boolean counterparts.\n\nWe cannot arbitrarily convert numbers because that will drop precision for numbers that require more than 32 bits to represent them.\n\n\n## Streaming\n\nPut this in your pipe and smoke it.\n\n### `logfmt.streamParser()`\n\nCreates a streaming parser that will automatically split and parse incoming lines and\nemit javascript objects.\n\nStream in from STDIN\n\n```javascript\nprocess.stdin.pipe(logfmt.streamParser())\n```\n\nOr pipe from an HTTP request\n\n```javascript\nreq.pipe(logfmt.streamParser())\n```\n\n### `logfmt.streamStringify([options])`\n\nPipe objects into the stream and it will write logfmt.\nYou can customize the delimiter via the `options` object, which\ndefaults to `\\n` (newlines).\n\n```javascript\n var parseJSON = function(line) {\n if(!line) return;\n this.queue(JSON.parse(line.trim()))\n }\n\n process.stdin\n .pipe(split())\n .pipe(through(parseJSON))\n .pipe(logfmt.streamStringify())\n .pipe(process.stdout)\n```\n\n#### Example\n\n\nExample command line of parsing logfmt and echoing objects to STDOUT:\n\n```javascript\nvar logfmt = require('logfmt');\nvar through = require('through');\n\nprocess.stdin\n .pipe(logfmt.streamParser())\n .pipe(through(function(object){\n console.log(object);\n }))\n```\n\nExample HTTP request parsing logfmt and echoing objects to STDOUT:\n\n```javascript\nvar http = require('http');\nvar logfmt = require('logfmt');\nvar through = require('through');\n\nhttp.createServer(function (req, res) {\n req.pipe(logfmt.streamParser())\n .pipe(through(function(object){\n console.log(object);\n }))\n\n res.writeHead(200, {'Content-Type': 'text/plain'});\n res.end('OK');\n}).listen(3000);\n```\n\n## express/restify parsing middleware\n\n```javascript\n // streaming\n app.use(logfmt.bodyParserStream());\n // buffering\n app.use(logfmt.bodyParser());\n```\n\n#### `logfmt.bodyParserStream([opts])`\n\nValid Options:\n\n- `contentType`: defaults to `application/logplex-1`\n\nIf you use the `logfmt.bodyParserStream()` for a body parser,\nyou will have a `req.body` that is a readable stream.\n\nPipes FTW:\n\n```javascript\nvar app = require('express')();\nvar http = require('http');\nvar through = require('through');\nvar logfmt = require('logfmt');\n\napp.use(logfmt.bodyParserStream());\n\napp.post('/logs', function(req, res){\n if(!req.body) return res.send('OK');\n\n req.body.pipe(through(function(line){\n console.dir(line);\n }))\n\n res.send('OK');\n})\n\nhttp.createServer(app).listen(3000);\n```\n\nOr you can just use the `readable` event:\n\n```javascript\nvar app = require('express')();\nvar http = require('http');\nvar logfmt = require('logfmt');\n\napp.use(logfmt.bodyParserStream());\n\n// req.body is now a Readable Stream\napp.post('/logs', function(req, res){\n req.body.on('readable', function(){\n var parsedLine = req.body.read();\n if(parsedLine) console.log(parsedLine);\n else res.send('OK');\n })\n})\n\nhttp.createServer(app).listen(3000);\n```\n\n### Non-Streaming\n\n#### `logfmt.bodyParser([opts])`\n\nValid Options:\n\n- `contentType`: defaults to `application/logplex-1`\n\nIf you use the `logfmt.bodyParser()` for a body parser,\nyou will have a `req.body` that is an array of objects.\n\n```javascript\nvar logfmt = require('logfmt');\n\napp.use(logfmt.bodyParser());\n\n// req.body is now an array of objects\napp.post('/logs', function(req, res){\n console.log('BODY: ' + JSON.stringify(req.body));\n req.body.forEach(function(data){\n console.log(data);\n });\n res.send('OK');\n})\n\nhttp.createServer(app).listen(3000);\n```\n\ntest it:\n\n```bash\ncurl -X POST --header 'Content-Type: application/logplex-1' -d \"foo=bar a=14 baz=\\\"hello kitty\\\" cool%story=bro f %^asdf\" http://localhost:3000/logs\n```\n\n## logging\n\nLog an object to `logfmt.stream` (defaults to STDOUT)\n\nUses the `logfmt.stringify` function to write the result to `logfmt.stream`\n\n```javascript\nlogfmt.log({foo: \"bar\", a: 14, baz: 'hello kitty'})\n//=> foo=bar a=14 baz=\"hello kitty\"\n//> undefined\n```\n\n### `logfmt.log(object, [stream])`\n\nDefaults to logging to `process.stdout`\n\n```javascript\nlogfmt.log({ \"foo\": \"bar\", \"a\": 14, baz: 'hello kitty'})\n//=> foo=bar a=14 baz=\"hello kitty\"\n```\n\n#### customizing logging location\n\n`logfmt.log()` Accepts as 2nd argument anything that responds to `write(string)`\n```javascript\nvar logfmt = require('logfmt');\nlogfmt.log({ \"foo\": \"bar\", \"a\": 14, baz: 'hello kitty'}, process.stderr)\n//=> foo=bar a=14 baz=\"hello kitty\"\n```\n\nOverwrite the default global location by setting `logfmt.stream`\n```javascript\nvar logfmt = require('logfmt');\nlogfmt.stream = process.stderr\n\nlogfmt.log({ \"foo\": \"bar\", \"a\": 14, baz: 'hello kitty'})\n//=> foo=bar a=14 baz=\"hello kitty\"\n```\n\nYou can have multiple, isolated logfmts by using `new`.\n\n```javascript\nvar logfmt = require('logfmt');\nvar errorLogger = new logfmt;\nerrorLogger.stream = process.stderr\n\nlogfmt.log({hello: 'stdout'});\n//=> hello=stdout\n\nerrorLogger.log({hello: 'stderr'});\n//=> hello=stderr\n```\n\n### `logfmt.namespace(object)`\n\nReturns a new `logfmt` with object's data included in every `log` call.\n\n```javascript\nvar logfmt = require('logfmt').namespace({app: 'logfmt'});\n\nlogfmt.log({ \"foo\": \"bar\", \"a\": 14, baz: 'hello kitty'})\n//=> app=logfmt foo=bar a=14 baz=\"hello kitty\"\n\nlogfmt.log({})\n//=> app=logfmt\n\nlogfmt.log({hello: 'world'})\n//=> app=logfmt hello=world\n```\n\n### `logfmt.time([label])`\n\nLog how long something takes.\nReturns a new `logfmt` with elapsed milliseconds included in every `log` call.\n\n- `label`: optional name for the milliseconds key. defaults to: `elapsed=ms`\n\n```javascript\nvar timer = logfmt.time();\ntimer.log();\n//=> elapsed=1ms\n```\n\nString `label` changes the key to `=ms`\n\n```javascript\nvar timer = logfmt.time('time');\ntimer.log();\n//=> time=1ms\ntimer.log();\n//=> time=2ms\n```\n\nIf you'd like to include data, just chain a call to namespace.\n\n```javascript\nvar timer = logfmt.time('time').namespace({foo: 'bar'});\ntimer.log();\n//=> time=1ms foo=bar\ntimer.log();\n//=> time=2ms foo=bar\n```\n\n### `logfmt.error(error)`\n\nAccepts a Javascript `Error` object and converts it to logfmt format.\n\nIt will print up to `logfmt.maxErrorLines` lines.\n\n```javascript\nvar logfmt = require('logfmt');\nlogfmt.error(new Error('test error'));\n//=> at=error id=12345 message=\"test error\"\n//=> at=error id=12345 line=0 trace=\"Error: test error\"\n//=> ...\n```\n\n## express/restify logging middleware\n\n```javascript\napp.use(logfmt.requestLogger());\n//=> ip=127.0.0.1 time=2013-08-05T20:50:19.216Z method=POST path=/logs status=200 content_length=337 content_type=application/logplex-1 elapsed=4ms\n```\n\n#### `logfmt.requestLogger([options], [formatter(req, res)])`\n\nIf no formatter is supplied it will default to `logfmt.requestLogger.commonFormatter` which is based\non having similiar fields to the Apache Common Log format.\n\nValid Options:\n\n- `immediate`: log before call to `next()` (ie: before the request finishes)\n- `elapsed`: renames the `elapsed` key to a key of your choice when in\n non-immediate mode\n\nDefaults to `immediate: true` and `elapsed: 'elapsed'`\n\n```javascript\napp.use(logfmt.requestLogger({immediate: true}, function(req, res){\n return {\n method: req.method\n }\n}));\n//=> method=POST\n```\n\n```javascript\napp.use(logfmt.requestLogger({elapsed: 'request.time'}, function(req, res){\n return {\n \"request.method\": req.method\n }\n}));\n//=> request.method=POST request.time=12ms\n```\n\n##### `formatter(req, res)`\n\nA formatter takes the request and response and returns a JSON object for `logfmt.log`\n\n```javascript\napp.use(logfmt.requestLogger(function(req, res){\n return {\n method: req.method\n }\n}));\n//=> method=POST elapsed=4ms\n```\n\nIt's always possible to piggyback on top of the `commonFormatter`\n\n```javascript\napp.use(logfmt.requestLogger(function(req, res){\n var data = logfmt.requestLogger.commonFormatter(req, res)\n return {\n ip: data.ip,\n time: data.time,\n foo: 'bar'\n };\n}));\n//=> ip=127.0.0.1 time=2013-08-05T20:50:19.216Z foo=bar elapsed=4ms\n```\n\n# Development\n\nPull Requests welcome.\n\n## Tests\n\n > npm test\n\n# License\n\nMIT\n", "readmeFilename": "README.md", "repository": { "type": "git", "url": "git+https://github.com/csquared/node-logfmt.git" }, "scripts": { "test": "mocha" }, "version": "1.2.0" }