Skip to content

Commit fecc373

Browse files
committedApr 14, 2016
Inivial version
0 parents  commit fecc373

6 files changed

+278
-0
lines changed
 

‎.editorconfig

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Set this file as the topmost .editorconfig
2+
root = true
3+
4+
[*.{js,json}]
5+
indent_style = space
6+
indent_size = 2
7+
end_of_line = lf
8+
charset = utf-8
9+
trim_trailing_whitespace = true
10+
insert_final_newline = true

‎.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
node_modules/
2+
.DS_Store
3+
key.json

‎README.md

+93
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
# bunyan-stackdriver
2+
3+
**Bunyan stream for StackDriver (Google Cloud Logging API) integration**
4+
5+
## Installation
6+
7+
First install bunyan...
8+
9+
```bash
10+
npm install bunyan
11+
```
12+
13+
Then install bunyan-stackdriver
14+
15+
```bash
16+
npm install bunyan-stackdriver
17+
```
18+
19+
## Setup
20+
21+
1. Enable [Google Cloud Logging API](https://console.cloud.google.com/apis/api/logging.googleapis.com/overview) in your Google Developer Console.
22+
2. [Create a new Client ID](https://console.cloud.google.com/apis/credentials) for a Service Account (JSON Key) and download it.
23+
3. Start using `bunyan-stackdriver` to create log your messages
24+
25+
## Basic usage
26+
27+
```javascript
28+
var bunyan = require("bunyan"),
29+
BunyanStackDriver = require('bunyan-stackdriver'),
30+
log;
31+
32+
log = bunyan.createLogger({
33+
name: "myApp",
34+
stream: new BunyanStackDriver({
35+
authJSON: require("./your-JSON-key.json"),
36+
project: "your_project_id",
37+
log_id: "default"
38+
}),
39+
level: "error"
40+
});
41+
42+
log.error("hello bunyan user");
43+
```
44+
45+
You can also pass an optional error handler.
46+
47+
```javascript
48+
new BunyanStackDriver({
49+
authJSON: require("./your-JSON-key.json"),
50+
project: "your_project_id",
51+
log_id: "default"
52+
}, function(error){
53+
console.log(error);
54+
});
55+
```
56+
57+
##Custom Formatters
58+
59+
By default the logs are formatted like so: `[LOG_LEVEL] message`, unless you specify a `customFormatter` function.
60+
61+
```javascript
62+
log = bunyan.createLogger({
63+
name: "myApp",
64+
stream: new BunyanStackDriver({
65+
authJSON: require("./your-JSON-key.json"),
66+
project: "your_project_id",
67+
log_id: "default"
68+
customFormatter: function(record, levelName){
69+
return {text: "[" + levelName + "] " + record.msg }
70+
}
71+
}),
72+
level: "error"
73+
});
74+
```
75+
76+
## Links
77+
78+
[Stackdriver Logging - Method entries.write](https://cloud.google.com/logging/docs/api/ref_v2beta1/rest/v2beta1/entries/write)
79+
80+
[Google Cloud Logging API beta nodejs client source code](https://github.com/google/google-api-nodejs-client/blob/master/apis/logging/v2beta1.js)
81+
82+
83+
## License
84+
85+
MIT License
86+
87+
Copyright (C) 2016 Martin Lazarov
88+
89+
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:
90+
91+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
92+
93+
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.

‎example.js

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
var bunyan = require("bunyan"),
2+
BunyanStackDriver = require('bunyan-stackdriver'),
3+
log;
4+
5+
log = bunyan.createLogger({
6+
name: "myApp",
7+
stream: new BunyanStackDriver({
8+
authJSON: require("./your-JSON-key.json"),
9+
project: "your_project_id",
10+
log_id: "default"
11+
}),
12+
level: "error"
13+
});
14+
15+
log.error("hello bunyan user");

‎lib/bunyan-stackdriver.js

+122
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
var util = require('util'),
2+
google = require('googleapis');
3+
4+
var glogging = google.logging("v2beta1");
5+
6+
const loggingScopes = [
7+
//'https://www.googleapis.com/auth/logging.read',
8+
'https://www.googleapis.com/auth/logging.write',
9+
//'https://www.googleapis.com/auth/logging.admin',
10+
//'https://www.googleapis.com/auth/cloud-platform'
11+
];
12+
13+
const nameFromLevel = {
14+
10: 'trace',
15+
20: 'debug',
16+
30: 'info',
17+
40: 'warn',
18+
50: 'error',
19+
60: 'fatal'
20+
};
21+
const mapLevelToSeverity = {
22+
trace: 'DEBUG',
23+
debug: 'DEBUG',
24+
info: 'INFO',
25+
warn: 'WARNING',
26+
error: 'ERROR',
27+
fatal: 'EMERGENCY'
28+
}
29+
30+
function getNow() {
31+
var d = new Date();
32+
return JSON.parse(JSON.stringify(d).replace('Z', '000Z'));
33+
}
34+
35+
function BunyanStackDriver(options, error) {
36+
options = options || {};
37+
if (!options.project) {
38+
throw new Error('Project cannot be null');
39+
} else {
40+
41+
this.customFormatter = options.customFormatter;
42+
this.project_id = options.project;
43+
this.log_id = options.log_id || 'default';
44+
this.error = error || function() {};
45+
46+
// https://cloud.google.com/logging/docs/api/ref_v2beta1/rest/v2beta1/LogEntry#LogSeverity
47+
if (options.severity) {
48+
this.severity = options.severity || 'DEFAULT';
49+
}
50+
51+
// object(MonitoredResource)
52+
// https://cloud.google.com/logging/docs/api/ref_v2beta1/rest/v2beta1/MonitoredResource
53+
this.resource = options.resource || {type: 'global'};
54+
55+
}
56+
57+
this.getLoggingClient = function (callback) {
58+
google.auth.fromJSON(options.authJSON, function (err, authClient){
59+
if (err) {
60+
return callback(err);
61+
}
62+
if (authClient.createScopedRequired && authClient.createScopedRequired()) {
63+
authClient = authClient.createScoped(loggingScopes);
64+
}
65+
callback(null, authClient);
66+
});
67+
}
68+
}
69+
70+
BunyanStackDriver.prototype.write = function write(record, callback) {
71+
var self = this,
72+
levelName,
73+
message;
74+
75+
if (typeof record === 'string') {
76+
record = JSON.parse(record);
77+
}
78+
79+
levelName = nameFromLevel[record.level];
80+
81+
try {
82+
83+
if(self.customFormatter){
84+
message = self.customFormatter(record, levelName);
85+
}else if(typeof(record) == "string"){
86+
message = { text: util.format('[%s] %s', levelName.toUpperCase(), record.msg)}
87+
}else{
88+
message = record;
89+
}
90+
} catch(err) {
91+
return self.error(err);
92+
}
93+
94+
self.getLoggingClient(function (err, authClient) {
95+
var params = {
96+
auth: authClient,
97+
resource: {
98+
//logName: "projects/" + self.project_id + "/logs/" + self.log_id,
99+
//resource: self.resource,
100+
//labels: {},
101+
entries: [{
102+
logName: "projects/" + self.project_id + "/logs/" + self.log_id,
103+
resource: self.resource,
104+
//timestamp: getNow(),
105+
severity: mapLevelToSeverity[levelName] || 'DEFAULT',
106+
//insertId,
107+
//httpRequest,
108+
//labels,
109+
//operation,
110+
[(message instanceof Object)?'jsonPayload':'textPayload']: message
111+
}],
112+
partialSuccess: true
113+
}
114+
};
115+
116+
glogging.entries.write(params, function(err,data){
117+
if(err) return self.error(err);
118+
});
119+
});
120+
};
121+
122+
module.exports = BunyanStackDriver;

‎package.json

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
{
2+
"name": "bunyan-stackdriver",
3+
"version": "0.0.1",
4+
"description": "StackDriver stream for Bunyan",
5+
"main": "./lib/bunyan-stackdriver",
6+
"repository": {
7+
"type": "git",
8+
"url": "git://git@github.com/mlazarov/bunyan-stackdriver.git"
9+
},
10+
"keywords": [
11+
"google",
12+
"gce",
13+
"gcp",
14+
"stackdriver",
15+
"logging"
16+
],
17+
"author": "Martin Lazarov <martin@lazarov.bg>",
18+
"license": "MIT",
19+
"bugs": {
20+
"url": "https://github.com/mlazarov/bunyan-stackdriver/issues"
21+
},
22+
"homepage": "https://github.com/mlazarov/bunyan-stackdriver",
23+
"dependencies": {
24+
"googleapis": "^4.0.0"
25+
},
26+
"devDependencies": {
27+
"bunyan": "^1.3.3"
28+
},
29+
"maintainers": [
30+
"mlazarov <martin@lazarov.bg>"
31+
],
32+
"scripts": {
33+
"test": "echo \"Error: no test specified\" && exit 1"
34+
}
35+
}

0 commit comments

Comments
 (0)
Failed to load comments.