-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathizaya.js
More file actions
143 lines (126 loc) · 4.1 KB
/
Copy pathizaya.js
File metadata and controls
143 lines (126 loc) · 4.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
var MongoClient = require('mongodb').MongoClient;
var assert = require('assert');
var _ = require('underscore');
var dbConfigs = {};
var mongoURL;
var logLevels = ['info', 'warn', 'error'];
_.each(logLevels, (level) => {
exports[level] = _.partial(logAtLevel, null, level);
});
/**
* Initialize this library to log to a default collection
* @param {Object} config Properties of the mongo collection to use for default
* log functions
* @return void
*/
exports.init = function(config){
assert(config.url, 'No URL provided');
assert(!config.cappedMax || config.cappedSize, "Must specify a cappedSize for capped collections");
dbConfigs.default = {
collection : config.collection || 'logs',
capSize : config.cappedSize,
capMax : config.cappedMax
};
mongoURL = config.url;
};
/**
* Add a another namespace for logging to an additional collection
* @param {String} namespace extension of module name to place logging
* functions under
* @param {String} additionalCollection name of new collection in database
* @param {Object} config configuration for collection
* @param {Boolean} inherit whether to inherit config properties
* from default
* @return void
*/
exports.addCollection = function(namespace, additionalCollection, config, inherit){
assert(additionalCollection, 'Collection name must be provided');
assert(!exports[namespace], 'Namespace is already in use');
assert.notEqual('default', namespace, 'Cannot use "default" namespace as it would override base config options');
// build log level functions object and export
exports[namespace] = _.reduce(logLevels, (memo, level) => {
memo[level] = _.partial(logAtLevel, namespace, level);
return memo;
}, {});
config = config || {};
if (inherit){
dbConfigs[namespace] = _.defaults(config, {collection: additionalCollection}, dbConfigs.default);
} else {
dbConfigs[namespace] = _.defaults(config, {collection: additionalCollection});
}
};
/**
* Execute creation of log(s) with the provided log level
* @param {String} level Log level
* @param {Array|Object} content Object(s) with content for logs
* @param {Function} callback
* @return void
*/
function logAtLevel(logSet, level, content, callback){
if (!_.isString(content) && !_.isObject(content) && !_.isArray(content)){
if (_.isFunction(callback)){
callback(new Error('Log must be a string, object, or array of objects'));
}
return;
}
// convert string to document object
if (_.isString(content)){
content = {message : content};
}
// convert single doc to an array so that we can always use insertMany
if (!_.isArray(content)){
content = [content];
}
var created = new Date();
// add metadata to each log
var logItems = _.map(content, (obj) => {
return {
created : created,
level : level,
content : obj
};
});
connectAndFetch(logSet, (err, db, logCollection) => {
if (err){
if (_.isFunction(callback)){
callback(err);
}
return;
}
logCollection.insertMany(logItems, (err, result) => {
db.close();
if (_.isFunction(callback)){
callback(err, result);
}
});
});
}
/**
* Connect to the database and retrieve the log collection
* @param {Function} callback Function with err, db, and collection params. The
* db is passed back so that it can be closed later
* @return void
*/
function connectAndFetch(logSet, callback){
MongoClient.connect(mongoURL, function(err, db) {
if (err){
callback(err);
return;
}
var fetchConfig = logSet ? dbConfigs[logSet] : dbConfigs.default;
// capped collections require an explicit createCollection call, so we always
// send a creation request, and it will simply fetch the collection if it
// already exists
var collection = db.createCollection(fetchConfig.collection, {
capped : fetchConfig.capSize ? true : false,
size : fetchConfig.capSize,
max : fetchConfig.capMax
}, (err, collection) => {
if (err){
callback(err);
return;
}
callback(null, db, collection);
});
});
}