passenger 5.0.21 → 5.0.22
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of passenger might be problematic. Click here for more details.
- checksums.yaml +8 -8
- checksums.yaml.gz.asc +7 -7
- data.tar.gz.asc +7 -7
- data/CHANGELOG +38 -2
- data/CONTRIBUTORS +3 -0
- data/README.md +5 -1
- data/bin/passenger-status +2 -7
- data/build/agent.rb +2 -0
- data/build/cxx_dependency_map.rb +1464 -162
- data/build/node_tests.rb +1 -1
- data/build/packaging.rb +1 -1
- data/dev/ci/run_travis.sh +1 -1
- data/dev/vagrant/provision.sh +1 -1
- data/npm-shrinkwrap.json +635 -125
- data/package.json +1 -1
- data/resources/templates/standalone/config.erb +33 -161
- data/resources/templates/standalone/global.erb +15 -0
- data/resources/templates/standalone/http.erb +40 -0
- data/resources/templates/standalone/mass_deployment_default_server.erb +11 -0
- data/resources/templates/standalone/rails_asset_pipeline.erb +22 -0
- data/resources/templates/standalone/server.erb +58 -0
- data/src/agent/Core/ApiServer.h +37 -32
- data/src/agent/Core/ApplicationPool/BasicGroupInfo.h +1 -1
- data/src/agent/Core/ApplicationPool/BasicProcessInfo.h +6 -0
- data/src/agent/Core/ApplicationPool/Common.h +1 -1
- data/src/agent/Core/ApplicationPool/Group/OutOfBandWork.cpp +1 -1
- data/src/agent/Core/ApplicationPool/Group/ProcessListManagement.cpp +4 -0
- data/src/agent/Core/ApplicationPool/Implementation.cpp +2 -2
- data/src/agent/Core/ApplicationPool/Options.h +18 -1
- data/src/agent/Core/ApplicationPool/Pool.h +1 -1
- data/src/agent/Core/ApplicationPool/Pool/AnalyticsCollection.cpp +6 -6
- data/src/agent/Core/ApplicationPool/Pool/GeneralUtils.cpp +3 -3
- data/src/agent/Core/ApplicationPool/Pool/InitializationAndShutdown.cpp +1 -1
- data/src/agent/Core/ApplicationPool/Pool/Miscellaneous.cpp +6 -0
- data/src/agent/Core/ApplicationPool/Process.h +6 -1
- data/src/agent/Core/ApplicationPool/Socket.h +9 -12
- data/src/agent/Core/Controller.h +422 -0
- data/src/agent/Core/{RequestHandler → Controller}/AppResponse.h +2 -0
- data/src/agent/Core/{RequestHandler → Controller}/BufferBody.cpp +27 -5
- data/src/agent/Core/{RequestHandler → Controller}/CheckoutSession.cpp +61 -31
- data/src/agent/Core/{RequestHandler → Controller}/Client.h +5 -2
- data/src/agent/Core/{RequestHandler → Controller}/ForwardResponse.cpp +93 -42
- data/src/agent/Core/{RequestHandler → Controller}/Hooks.cpp +107 -60
- data/src/agent/Core/Controller/Implementation.cpp +38 -0
- data/src/agent/Core/{RequestHandler → Controller}/InitRequest.cpp +134 -80
- data/src/agent/Core/Controller/InitializationAndShutdown.cpp +165 -0
- data/src/agent/Core/{RequestHandler/Utils.cpp → Controller/InternalUtils.cpp} +49 -32
- data/src/agent/Core/Controller/Miscellaneous.cpp +116 -0
- data/src/agent/Core/{RequestHandler → Controller}/Request.h +6 -4
- data/src/agent/Core/{RequestHandler → Controller}/SendRequest.cpp +205 -130
- data/src/agent/Core/Controller/StateInspectionAndConfiguration.cpp +161 -0
- data/src/agent/Core/{RequestHandler → Controller}/TurboCaching.h +3 -0
- data/src/agent/Core/CoreMain.cpp +62 -51
- data/src/agent/Core/OptionParser.h +24 -0
- data/src/agent/Core/ResponseCache.h +5 -5
- data/src/agent/Core/SpawningKit/Config.h +2 -2
- data/src/agent/Core/SpawningKit/SmartSpawner.h +1 -1
- data/src/agent/Core/UnionStation/{Core.h → Context.h} +14 -18
- data/src/agent/Core/UnionStation/StopwatchLog.h +3 -2
- data/src/agent/Core/UnionStation/Transaction.h +7 -7
- data/src/agent/Shared/ApiServerUtils.h +9 -1
- data/src/agent/UstRouter/ApiServer.h +5 -2
- data/src/agent/UstRouter/Controller.h +27 -9
- data/src/agent/UstRouter/UstRouterMain.cpp +1 -0
- data/src/agent/Watchdog/ApiServer.h +5 -2
- data/src/apache2_module/ConfigurationCommands.cpp +7 -0
- data/src/apache2_module/ConfigurationFields.hpp +2 -0
- data/src/apache2_module/ConfigurationSetters.cpp +24 -0
- data/src/apache2_module/CreateDirConfig.cpp +1 -0
- data/src/apache2_module/Hooks.cpp +6 -5
- data/src/apache2_module/MergeDirConfig.cpp +7 -0
- data/src/apache2_module/SetHeaders.cpp +5 -0
- data/src/cxx_supportlib/Constants.h +5 -3
- data/src/cxx_supportlib/SafeLibev.h +2 -1
- data/src/cxx_supportlib/UnionStationFilterSupport.h +2 -1
- data/src/cxx_supportlib/Utils/ReleaseableScopedPointer.h +70 -0
- data/src/cxx_supportlib/vendor-modified/boost/libs/regex/src/regex_raw_buffer.cpp +6 -6
- data/src/helper-scripts/node-loader.js +59 -0
- data/src/nginx_module/CacheLocationConfig.c +48 -0
- data/src/nginx_module/ConfigurationCommands.c +20 -0
- data/src/nginx_module/ConfigurationFields.h +4 -0
- data/src/nginx_module/CreateLocationConfig.c +8 -0
- data/src/nginx_module/MergeLocationConfig.c +12 -0
- data/src/nodejs_supportlib/phusion_passenger/log_express.js +106 -0
- data/src/nodejs_supportlib/phusion_passenger/log_mongodb.js +203 -0
- data/src/nodejs_supportlib/phusion_passenger/ustreporter.js +227 -0
- data/src/nodejs_supportlib/phusion_passenger/ustrouter_connector.js +446 -0
- data/src/nodejs_supportlib/vendor-copy/codify/codify.js +44 -0
- data/src/nodejs_supportlib/vendor-copy/codify/package.json +29 -0
- data/src/nodejs_supportlib/vendor-copy/continuation-local-storage/context.js +200 -0
- data/src/nodejs_supportlib/vendor-copy/continuation-local-storage/node_modules/async-listener/glue.js +488 -0
- data/src/nodejs_supportlib/vendor-copy/continuation-local-storage/node_modules/async-listener/index.js +407 -0
- data/src/nodejs_supportlib/vendor-copy/continuation-local-storage/node_modules/async-listener/node_modules/shimmer/index.js +90 -0
- data/src/nodejs_supportlib/vendor-copy/continuation-local-storage/node_modules/async-listener/node_modules/shimmer/package.json +40 -0
- data/src/nodejs_supportlib/vendor-copy/continuation-local-storage/node_modules/async-listener/package.json +54 -0
- data/src/nodejs_supportlib/vendor-copy/continuation-local-storage/node_modules/emitter-listener/listener.js +160 -0
- data/src/nodejs_supportlib/vendor-copy/continuation-local-storage/node_modules/emitter-listener/node_modules/shimmer/index.js +90 -0
- data/src/nodejs_supportlib/vendor-copy/continuation-local-storage/node_modules/emitter-listener/node_modules/shimmer/package.json +40 -0
- data/src/nodejs_supportlib/vendor-copy/continuation-local-storage/node_modules/emitter-listener/package.json +46 -0
- data/src/nodejs_supportlib/vendor-copy/continuation-local-storage/package.json +56 -0
- data/src/nodejs_supportlib/vendor-copy/network-byte-order/lib/index.js +102 -0
- data/src/nodejs_supportlib/vendor-copy/network-byte-order/package.json +51 -0
- data/src/nodejs_supportlib/vendor-copy/winston/LICENSE +19 -0
- data/src/nodejs_supportlib/vendor-copy/winston/lib/winston.js +165 -0
- data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/common.js +483 -0
- data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/config.js +62 -0
- data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/config/cli-config.js +35 -0
- data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/config/npm-config.js +27 -0
- data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/config/syslog-config.js +31 -0
- data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/container.js +127 -0
- data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/exception.js +56 -0
- data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/logger.js +701 -0
- data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/transports.js +34 -0
- data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/transports/console.js +128 -0
- data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/transports/daily-rotate-file.js +601 -0
- data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/transports/file.js +675 -0
- data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/transports/http.js +232 -0
- data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/transports/memory.js +89 -0
- data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/transports/transport.js +135 -0
- data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/transports/webhook.js +146 -0
- data/src/nodejs_supportlib/vendor-copy/winston/node_modules/async/LICENSE +19 -0
- data/src/nodejs_supportlib/vendor-copy/winston/node_modules/async/lib/async.js +1283 -0
- data/src/nodejs_supportlib/vendor-copy/winston/node_modules/async/package.json +66 -0
- data/src/nodejs_supportlib/vendor-copy/winston/node_modules/async/support/sync-package-managers.js +53 -0
- data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/MIT-LICENSE.txt +23 -0
- data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/lib/colors.js +176 -0
- data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/lib/custom/trap.js +45 -0
- data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/lib/custom/zalgo.js +104 -0
- data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/lib/extendStringPrototype.js +118 -0
- data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/lib/index.js +12 -0
- data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/lib/maps/america.js +12 -0
- data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/lib/maps/rainbow.js +13 -0
- data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/lib/maps/random.js +8 -0
- data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/lib/maps/zebra.js +5 -0
- data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/lib/styles.js +77 -0
- data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/lib/system/supports-colors.js +61 -0
- data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/package.json +35 -0
- data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/safe.js +9 -0
- data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/themes/generic-logging.js +12 -0
- data/src/nodejs_supportlib/vendor-copy/winston/node_modules/cycle/cycle.js +170 -0
- data/src/nodejs_supportlib/vendor-copy/winston/node_modules/cycle/package.json +30 -0
- data/src/nodejs_supportlib/vendor-copy/winston/node_modules/eyes/LICENSE +20 -0
- data/src/nodejs_supportlib/vendor-copy/winston/node_modules/eyes/lib/eyes.js +236 -0
- data/src/nodejs_supportlib/vendor-copy/winston/node_modules/eyes/package.json +42 -0
- data/src/nodejs_supportlib/vendor-copy/winston/node_modules/isstream/LICENSE.md +11 -0
- data/src/nodejs_supportlib/vendor-copy/winston/node_modules/isstream/isstream.js +27 -0
- data/src/nodejs_supportlib/vendor-copy/winston/node_modules/isstream/package.json +42 -0
- data/src/nodejs_supportlib/vendor-copy/winston/node_modules/pkginfo/LICENSE +19 -0
- data/src/nodejs_supportlib/vendor-copy/winston/node_modules/pkginfo/lib/pkginfo.js +136 -0
- data/src/nodejs_supportlib/vendor-copy/winston/node_modules/pkginfo/package.json +56 -0
- data/src/nodejs_supportlib/vendor-copy/winston/node_modules/stack-trace/License +19 -0
- data/src/nodejs_supportlib/vendor-copy/winston/node_modules/stack-trace/lib/stack-trace.js +111 -0
- data/src/nodejs_supportlib/vendor-copy/winston/node_modules/stack-trace/package.json +33 -0
- data/src/nodejs_supportlib/vendor-copy/winston/package.json +87 -0
- data/src/ruby_supportlib/phusion_passenger.rb +3 -4
- data/src/ruby_supportlib/phusion_passenger/admin_tools/instance.rb +19 -2
- data/src/ruby_supportlib/phusion_passenger/apache2/config_options.rb +8 -0
- data/src/ruby_supportlib/phusion_passenger/config/list_instances_command.rb +2 -6
- data/src/ruby_supportlib/phusion_passenger/config/reopen_logs_command.rb +13 -0
- data/src/ruby_supportlib/phusion_passenger/config/restart_app_command.rb +3 -0
- data/src/ruby_supportlib/phusion_passenger/config/utils.rb +9 -7
- data/src/ruby_supportlib/phusion_passenger/config/validate_install_command.rb +8 -1
- data/src/ruby_supportlib/phusion_passenger/constants.rb +3 -1
- data/src/ruby_supportlib/phusion_passenger/native_support.rb +20 -4
- data/src/ruby_supportlib/phusion_passenger/nginx/config_options.rb +8 -0
- data/src/ruby_supportlib/phusion_passenger/packaging.rb +1 -0
- data/src/ruby_supportlib/phusion_passenger/platform_info/apache_detector.rb +1 -1
- data/src/ruby_supportlib/phusion_passenger/platform_info/operating_system.rb +11 -4
- data/src/ruby_supportlib/phusion_passenger/rack/thread_handler_extension.rb +1 -1
- data/src/ruby_supportlib/phusion_passenger/standalone/config_options_list.rb +647 -0
- data/src/ruby_supportlib/phusion_passenger/standalone/config_utils.rb +229 -15
- data/src/ruby_supportlib/phusion_passenger/standalone/start_command.rb +35 -323
- data/src/ruby_supportlib/phusion_passenger/standalone/start_command/builtin_engine.rb +36 -12
- data/src/ruby_supportlib/phusion_passenger/standalone/start_command/nginx_engine.rb +123 -14
- data/src/ruby_supportlib/phusion_passenger/standalone/status_command.rb +32 -17
- data/src/ruby_supportlib/phusion_passenger/standalone/stop_command.rb +32 -21
- data/src/ruby_supportlib/phusion_passenger/standalone/version_command.rb +5 -5
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/README.md +2 -2
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/Rakefile +5 -1
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core.rb +68 -24
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/api.rb +9 -1
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/context.rb +9 -7
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/request_reporter.rb +3 -2
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/request_reporter/basics.rb +8 -5
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/simple_json.rb +395 -0
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/transaction.rb +10 -7
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/utils.rb +14 -0
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/version_data.rb +2 -2
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/ruby_versions.yml +4 -2
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/ruby_versions.yml.example +2 -2
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/ruby_versions.yml.travis +2 -2
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/ruby_versions.yml.travis-with-sudo +16 -0
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/Gemfile +1 -1
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/Gemfile.lock +2 -2
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/README.md +1 -1
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/lib/union_station_hooks_rails.rb +44 -17
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/lib/union_station_hooks_rails/active_support_cache_subscriber.rb +16 -7
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/lib/union_station_hooks_rails/version_data.rb +2 -2
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/union_station_hooks_rails.gemspec +1 -1
- metadata +99 -16
- metadata.gz.asc +7 -7
- data/resources/oss-binaries.phusionpassenger.com.crt +0 -248
- data/src/agent/Core/RequestHandler.h +0 -471
@@ -0,0 +1,675 @@
|
|
1
|
+
/*
|
2
|
+
* file.js: Transport for outputting to a local log file
|
3
|
+
*
|
4
|
+
* (C) 2010 Charlie Robbins
|
5
|
+
* MIT LICENCE
|
6
|
+
*
|
7
|
+
*/
|
8
|
+
|
9
|
+
var events = require('events'),
|
10
|
+
fs = require('fs'),
|
11
|
+
path = require('path'),
|
12
|
+
util = require('util'),
|
13
|
+
async = require('async'),
|
14
|
+
zlib = require('zlib'),
|
15
|
+
common = require('../common'),
|
16
|
+
Transport = require('./transport').Transport,
|
17
|
+
isWritable = require('isstream').isWritable,
|
18
|
+
Stream = require('stream').Stream,
|
19
|
+
os = require('os');
|
20
|
+
|
21
|
+
//
|
22
|
+
// ### function File (options)
|
23
|
+
// #### @options {Object} Options for this instance.
|
24
|
+
// Constructor function for the File transport object responsible
|
25
|
+
// for persisting log messages and metadata to one or more files.
|
26
|
+
//
|
27
|
+
var File = exports.File = function (options) {
|
28
|
+
var self = this;
|
29
|
+
Transport.call(this, options);
|
30
|
+
|
31
|
+
//
|
32
|
+
// Helper function which throws an `Error` in the event
|
33
|
+
// that any of the rest of the arguments is present in `options`.
|
34
|
+
//
|
35
|
+
function throwIf (target /*, illegal... */) {
|
36
|
+
Array.prototype.slice.call(arguments, 1).forEach(function (name) {
|
37
|
+
if (options[name]) {
|
38
|
+
throw new Error('Cannot set ' + name + ' and ' + target + 'together');
|
39
|
+
}
|
40
|
+
});
|
41
|
+
}
|
42
|
+
|
43
|
+
if (options.filename || options.dirname) {
|
44
|
+
throwIf('filename or dirname', 'stream');
|
45
|
+
this._basename = this.filename = options.filename
|
46
|
+
? path.basename(options.filename)
|
47
|
+
: 'winston.log';
|
48
|
+
|
49
|
+
this.dirname = options.dirname || path.dirname(options.filename);
|
50
|
+
this.options = options.options || { flags: 'a' };
|
51
|
+
|
52
|
+
//
|
53
|
+
// "24 bytes" is maybe a good value for logging lines.
|
54
|
+
//
|
55
|
+
this.options.highWaterMark = this.options.highWaterMark || 24;
|
56
|
+
}
|
57
|
+
else if (options.stream) {
|
58
|
+
throwIf('stream', 'filename', 'maxsize');
|
59
|
+
this._stream = options.stream;
|
60
|
+
this._isStreams2 = isWritable(this._stream);
|
61
|
+
this._stream.on('error', function(error){
|
62
|
+
self.emit('error', error);
|
63
|
+
});
|
64
|
+
//
|
65
|
+
// We need to listen for drain events when
|
66
|
+
// write() returns false. This can make node
|
67
|
+
// mad at times.
|
68
|
+
//
|
69
|
+
this._stream.setMaxListeners(Infinity);
|
70
|
+
}
|
71
|
+
else {
|
72
|
+
throw new Error('Cannot log to file without filename or stream.');
|
73
|
+
}
|
74
|
+
|
75
|
+
this.json = options.json !== false;
|
76
|
+
this.logstash = options.logstash || false;
|
77
|
+
this.colorize = options.colorize || false;
|
78
|
+
this.maxsize = options.maxsize || null;
|
79
|
+
this.rotationFormat = options.rotationFormat || false;
|
80
|
+
this.zippedArchive = options.zippedArchive || false;
|
81
|
+
this.maxFiles = options.maxFiles || null;
|
82
|
+
this.prettyPrint = options.prettyPrint || false;
|
83
|
+
this.label = options.label || null;
|
84
|
+
this.timestamp = options.timestamp != null ? options.timestamp : true;
|
85
|
+
this.eol = options.eol || os.EOL;
|
86
|
+
this.tailable = options.tailable || false;
|
87
|
+
this.depth = options.depth || null;
|
88
|
+
this.showLevel = options.showLevel === undefined ? true : options.showLevel;
|
89
|
+
this.maxRetries = options.maxRetries || 2;
|
90
|
+
|
91
|
+
if (this.json) {
|
92
|
+
this.stringify = options.stringify;
|
93
|
+
}
|
94
|
+
|
95
|
+
//
|
96
|
+
// Internal state variables representing the number
|
97
|
+
// of files this instance has created and the current
|
98
|
+
// size (in bytes) of the current logfile.
|
99
|
+
//
|
100
|
+
this._size = 0;
|
101
|
+
this._created = 0;
|
102
|
+
this._buffer = [];
|
103
|
+
this._draining = false;
|
104
|
+
this._opening = false;
|
105
|
+
this._failures = 0;
|
106
|
+
this._archive = null;
|
107
|
+
};
|
108
|
+
|
109
|
+
//
|
110
|
+
// Inherit from `winston.Transport`.
|
111
|
+
//
|
112
|
+
util.inherits(File, Transport);
|
113
|
+
|
114
|
+
//
|
115
|
+
// Expose the name of this Transport on the prototype
|
116
|
+
//
|
117
|
+
File.prototype.name = 'file';
|
118
|
+
|
119
|
+
//
|
120
|
+
// ### function log (level, msg, [meta], callback)
|
121
|
+
// #### @level {string} Level at which to log the message.
|
122
|
+
// #### @msg {string} Message to log
|
123
|
+
// #### @meta {Object} **Optional** Additional metadata to attach
|
124
|
+
// #### @callback {function} Continuation to respond to when complete.
|
125
|
+
// Core logging method exposed to Winston. Metadata is optional.
|
126
|
+
//
|
127
|
+
File.prototype.log = function (level, msg, meta, callback) {
|
128
|
+
if (this.silent) {
|
129
|
+
return callback(null, true);
|
130
|
+
}
|
131
|
+
|
132
|
+
//
|
133
|
+
// If failures exceeds maxRetries then we can't access the
|
134
|
+
// stream. In this case we need to perform a noop and return
|
135
|
+
// an error.
|
136
|
+
//
|
137
|
+
if (this._failures >= this.maxRetries) {
|
138
|
+
return callback(new Error('Transport is in a failed state.'));
|
139
|
+
}
|
140
|
+
|
141
|
+
var self = this;
|
142
|
+
|
143
|
+
if (typeof msg !== 'string') {
|
144
|
+
msg = '' + msg;
|
145
|
+
}
|
146
|
+
|
147
|
+
var output = common.log({
|
148
|
+
level: level,
|
149
|
+
message: msg,
|
150
|
+
meta: meta,
|
151
|
+
json: this.json,
|
152
|
+
logstash: this.logstash,
|
153
|
+
colorize: this.colorize,
|
154
|
+
prettyPrint: this.prettyPrint,
|
155
|
+
timestamp: this.timestamp,
|
156
|
+
showLevel: this.showLevel,
|
157
|
+
stringify: this.stringify,
|
158
|
+
label: this.label,
|
159
|
+
depth: this.depth,
|
160
|
+
formatter: this.formatter,
|
161
|
+
humanReadableUnhandledException: this.humanReadableUnhandledException
|
162
|
+
}) + this.eol;
|
163
|
+
|
164
|
+
|
165
|
+
if (!this.filename) {
|
166
|
+
//
|
167
|
+
// If there is no `filename` on this instance then it was configured
|
168
|
+
// with a raw `WriteableStream` instance and we should not perform any
|
169
|
+
// size restrictions.
|
170
|
+
//
|
171
|
+
this._write(output, callback);
|
172
|
+
this._size += output.length;
|
173
|
+
this._lazyDrain();
|
174
|
+
}
|
175
|
+
else {
|
176
|
+
this.open(function (err) {
|
177
|
+
if (err) {
|
178
|
+
//
|
179
|
+
// If there was an error enqueue the message
|
180
|
+
//
|
181
|
+
return self._buffer.push([output, callback]);
|
182
|
+
}
|
183
|
+
|
184
|
+
self._write(output, callback);
|
185
|
+
self._size += output.length;
|
186
|
+
self._lazyDrain();
|
187
|
+
});
|
188
|
+
}
|
189
|
+
};
|
190
|
+
|
191
|
+
//
|
192
|
+
// ### function _write (data, cb)
|
193
|
+
// #### @data {String|Buffer} Data to write to the instance's stream.
|
194
|
+
// #### @cb {function} Continuation to respond to when complete.
|
195
|
+
// Write to the stream, ensure execution of a callback on completion.
|
196
|
+
//
|
197
|
+
File.prototype._write = function(data, callback) {
|
198
|
+
if (this._isStreams2) {
|
199
|
+
this._stream.write(data);
|
200
|
+
return callback && process.nextTick(function () {
|
201
|
+
callback(null, true);
|
202
|
+
});
|
203
|
+
}
|
204
|
+
|
205
|
+
// If this is a file write stream, we could use the builtin
|
206
|
+
// callback functionality, however, the stream is not guaranteed
|
207
|
+
// to be an fs.WriteStream.
|
208
|
+
var ret = this._stream.write(data);
|
209
|
+
if (!callback) return;
|
210
|
+
if (ret === false) {
|
211
|
+
return this._stream.once('drain', function() {
|
212
|
+
callback(null, true);
|
213
|
+
});
|
214
|
+
}
|
215
|
+
process.nextTick(function () {
|
216
|
+
callback(null, true);
|
217
|
+
});
|
218
|
+
};
|
219
|
+
|
220
|
+
//
|
221
|
+
// ### function query (options, callback)
|
222
|
+
// #### @options {Object} Loggly-like query options for this instance.
|
223
|
+
// #### @callback {function} Continuation to respond to when complete.
|
224
|
+
// Query the transport. Options object is optional.
|
225
|
+
//
|
226
|
+
File.prototype.query = function (options, callback) {
|
227
|
+
if (typeof options === 'function') {
|
228
|
+
callback = options;
|
229
|
+
options = {};
|
230
|
+
}
|
231
|
+
|
232
|
+
var file = path.join(this.dirname, this.filename),
|
233
|
+
options = this.normalizeQuery(options),
|
234
|
+
buff = '',
|
235
|
+
results = [],
|
236
|
+
row = 0;
|
237
|
+
|
238
|
+
var stream = fs.createReadStream(file, {
|
239
|
+
encoding: 'utf8'
|
240
|
+
});
|
241
|
+
|
242
|
+
stream.on('error', function (err) {
|
243
|
+
if (stream.readable) {
|
244
|
+
stream.destroy();
|
245
|
+
}
|
246
|
+
if (!callback) return;
|
247
|
+
return err.code !== 'ENOENT'
|
248
|
+
? callback(err)
|
249
|
+
: callback(null, results);
|
250
|
+
});
|
251
|
+
|
252
|
+
stream.on('data', function (data) {
|
253
|
+
var data = (buff + data).split(/\n+/),
|
254
|
+
l = data.length - 1,
|
255
|
+
i = 0;
|
256
|
+
|
257
|
+
for (; i < l; i++) {
|
258
|
+
if (!options.start || row >= options.start) {
|
259
|
+
add(data[i]);
|
260
|
+
}
|
261
|
+
row++;
|
262
|
+
}
|
263
|
+
|
264
|
+
buff = data[l];
|
265
|
+
});
|
266
|
+
|
267
|
+
stream.on('close', function () {
|
268
|
+
if (buff) add(buff, true);
|
269
|
+
if (options.order === 'desc') {
|
270
|
+
results = results.reverse();
|
271
|
+
}
|
272
|
+
if (callback) callback(null, results);
|
273
|
+
});
|
274
|
+
|
275
|
+
function add(buff, attempt) {
|
276
|
+
try {
|
277
|
+
var log = JSON.parse(buff);
|
278
|
+
if (check(log)) push(log);
|
279
|
+
} catch (e) {
|
280
|
+
if (!attempt) {
|
281
|
+
stream.emit('error', e);
|
282
|
+
}
|
283
|
+
}
|
284
|
+
}
|
285
|
+
|
286
|
+
function push(log) {
|
287
|
+
if (options.rows && results.length >= options.rows) {
|
288
|
+
if (stream.readable) {
|
289
|
+
stream.destroy();
|
290
|
+
}
|
291
|
+
return;
|
292
|
+
}
|
293
|
+
|
294
|
+
if (options.fields) {
|
295
|
+
var obj = {};
|
296
|
+
options.fields.forEach(function (key) {
|
297
|
+
obj[key] = log[key];
|
298
|
+
});
|
299
|
+
log = obj;
|
300
|
+
}
|
301
|
+
|
302
|
+
results.push(log);
|
303
|
+
}
|
304
|
+
|
305
|
+
function check(log) {
|
306
|
+
if (!log) return;
|
307
|
+
|
308
|
+
if (typeof log !== 'object') return;
|
309
|
+
|
310
|
+
var time = new Date(log.timestamp);
|
311
|
+
if ((options.from && time < options.from)
|
312
|
+
|| (options.until && time > options.until)) {
|
313
|
+
return;
|
314
|
+
}
|
315
|
+
|
316
|
+
return true;
|
317
|
+
}
|
318
|
+
};
|
319
|
+
|
320
|
+
//
|
321
|
+
// ### function stream (options)
|
322
|
+
// #### @options {Object} Stream options for this instance.
|
323
|
+
// Returns a log stream for this transport. Options object is optional.
|
324
|
+
//
|
325
|
+
File.prototype.stream = function (options) {
|
326
|
+
var file = path.join(this.dirname, this.filename),
|
327
|
+
options = options || {},
|
328
|
+
stream = new Stream;
|
329
|
+
|
330
|
+
var tail = {
|
331
|
+
file: file,
|
332
|
+
start: options.start
|
333
|
+
};
|
334
|
+
|
335
|
+
stream.destroy = common.tailFile(tail, function (err, line) {
|
336
|
+
|
337
|
+
if(err){
|
338
|
+
return stream.emit('error',err);
|
339
|
+
}
|
340
|
+
|
341
|
+
try {
|
342
|
+
stream.emit('data', line);
|
343
|
+
line = JSON.parse(line);
|
344
|
+
stream.emit('log', line);
|
345
|
+
} catch (e) {
|
346
|
+
stream.emit('error', e);
|
347
|
+
}
|
348
|
+
});
|
349
|
+
|
350
|
+
return stream;
|
351
|
+
};
|
352
|
+
|
353
|
+
//
|
354
|
+
// ### function open (callback)
|
355
|
+
// #### @callback {function} Continuation to respond to when complete
|
356
|
+
// Checks to see if a new file needs to be created based on the `maxsize`
|
357
|
+
// (if any) and the current size of the file used.
|
358
|
+
//
|
359
|
+
File.prototype.open = function (callback) {
|
360
|
+
if (this.opening) {
|
361
|
+
//
|
362
|
+
// If we are already attempting to open the next
|
363
|
+
// available file then respond with a value indicating
|
364
|
+
// that the message should be buffered.
|
365
|
+
//
|
366
|
+
return callback(true);
|
367
|
+
}
|
368
|
+
else if (!this._stream || (this.maxsize && this._size >= this.maxsize)) {
|
369
|
+
//
|
370
|
+
// If we dont have a stream or have exceeded our size, then create
|
371
|
+
// the next stream and respond with a value indicating that
|
372
|
+
// the message should be buffered.
|
373
|
+
//
|
374
|
+
callback(true);
|
375
|
+
return this._createStream();
|
376
|
+
}
|
377
|
+
|
378
|
+
this._archive = this.zippedArchive ? this._stream.path : null;
|
379
|
+
|
380
|
+
//
|
381
|
+
// Otherwise we have a valid (and ready) stream.
|
382
|
+
//
|
383
|
+
callback();
|
384
|
+
};
|
385
|
+
|
386
|
+
//
|
387
|
+
// ### function close ()
|
388
|
+
// Closes the stream associated with this instance.
|
389
|
+
//
|
390
|
+
File.prototype.close = function () {
|
391
|
+
var self = this;
|
392
|
+
|
393
|
+
if (this._stream) {
|
394
|
+
this._stream.end();
|
395
|
+
this._stream.destroySoon();
|
396
|
+
|
397
|
+
this._stream.once('finish', function () {
|
398
|
+
self.emit('flush');
|
399
|
+
self.emit('closed');
|
400
|
+
});
|
401
|
+
}
|
402
|
+
};
|
403
|
+
|
404
|
+
//
|
405
|
+
// ### function flush ()
|
406
|
+
// Flushes any buffered messages to the current `stream`
|
407
|
+
// used by this instance.
|
408
|
+
//
|
409
|
+
File.prototype.flush = function () {
|
410
|
+
var self = this;
|
411
|
+
|
412
|
+
// If nothing to flush, there will be no "flush" event from native stream
|
413
|
+
// Thus, the "open" event will never be fired (see _createStream.createAndFlush function)
|
414
|
+
// That means, self.opening will never set to false and no logs will be written to disk
|
415
|
+
if (!this._buffer.length) {
|
416
|
+
return self.emit('flush');
|
417
|
+
}
|
418
|
+
|
419
|
+
//
|
420
|
+
// Iterate over the `_buffer` of enqueued messaged
|
421
|
+
// and then write them to the newly created stream.
|
422
|
+
//
|
423
|
+
this._buffer.forEach(function (item) {
|
424
|
+
var str = item[0],
|
425
|
+
callback = item[1];
|
426
|
+
|
427
|
+
process.nextTick(function () {
|
428
|
+
self._write(str, callback);
|
429
|
+
self._size += str.length;
|
430
|
+
});
|
431
|
+
});
|
432
|
+
|
433
|
+
//
|
434
|
+
// Quickly truncate the `_buffer` once the write operations
|
435
|
+
// have been started
|
436
|
+
//
|
437
|
+
self._buffer.length = 0;
|
438
|
+
|
439
|
+
//
|
440
|
+
// When the stream has drained we have flushed
|
441
|
+
// our buffer.
|
442
|
+
//
|
443
|
+
self._stream.once('drain', function () {
|
444
|
+
self.emit('flush');
|
445
|
+
self.emit('logged');
|
446
|
+
});
|
447
|
+
};
|
448
|
+
|
449
|
+
//
|
450
|
+
// ### @private function _createStream ()
|
451
|
+
// Attempts to open the next appropriate file for this instance
|
452
|
+
// based on the common state (such as `maxsize` and `_basename`).
|
453
|
+
//
|
454
|
+
File.prototype._createStream = function () {
|
455
|
+
var self = this;
|
456
|
+
this.opening = true;
|
457
|
+
|
458
|
+
(function checkFile (target) {
|
459
|
+
var fullname = path.join(self.dirname, target);
|
460
|
+
|
461
|
+
//
|
462
|
+
// Creates the `WriteStream` and then flushes any
|
463
|
+
// buffered messages.
|
464
|
+
//
|
465
|
+
function createAndFlush (size) {
|
466
|
+
if (self._stream) {
|
467
|
+
self._stream.end();
|
468
|
+
self._stream.destroySoon();
|
469
|
+
}
|
470
|
+
|
471
|
+
self._size = size;
|
472
|
+
self.filename = target;
|
473
|
+
self._stream = fs.createWriteStream(fullname, self.options);
|
474
|
+
self._isStreams2 = isWritable(self._stream);
|
475
|
+
self._stream.on('error', function(error){
|
476
|
+
if (self._failures < self.maxRetries) {
|
477
|
+
self._createStream();
|
478
|
+
self._failures++;
|
479
|
+
}
|
480
|
+
else {
|
481
|
+
self.emit('error', error);
|
482
|
+
}
|
483
|
+
});
|
484
|
+
//
|
485
|
+
// We need to listen for drain events when
|
486
|
+
// write() returns false. This can make node
|
487
|
+
// mad at times.
|
488
|
+
//
|
489
|
+
self._stream.setMaxListeners(Infinity);
|
490
|
+
|
491
|
+
//
|
492
|
+
// When the current stream has finished flushing
|
493
|
+
// then we can be sure we have finished opening
|
494
|
+
// and thus can emit the `open` event.
|
495
|
+
//
|
496
|
+
self.once('flush', function () {
|
497
|
+
// Because "flush" event is based on native stream "drain" event,
|
498
|
+
// logs could be written inbetween "self.flush()" and here
|
499
|
+
// Therefore, we need to flush again to make sure everything is flushed
|
500
|
+
self.flush();
|
501
|
+
|
502
|
+
self.opening = false;
|
503
|
+
self.emit('open', fullname);
|
504
|
+
});
|
505
|
+
//
|
506
|
+
// Remark: It is possible that in the time it has taken to find the
|
507
|
+
// next logfile to be written more data than `maxsize` has been buffered,
|
508
|
+
// but for sensible limits (10s - 100s of MB) this seems unlikely in less
|
509
|
+
// than one second.
|
510
|
+
//
|
511
|
+
self.flush();
|
512
|
+
compressFile();
|
513
|
+
}
|
514
|
+
|
515
|
+
function compressFile() {
|
516
|
+
if (self._archive) {
|
517
|
+
var gzip = zlib.createGzip();
|
518
|
+
|
519
|
+
var inp = fs.createReadStream(String(self._archive));
|
520
|
+
var out = fs.createWriteStream(self._archive + '.gz');
|
521
|
+
|
522
|
+
inp.pipe(gzip).pipe(out);
|
523
|
+
|
524
|
+
fs.unlink(String(self._archive));
|
525
|
+
self._archive = '';
|
526
|
+
}
|
527
|
+
}
|
528
|
+
|
529
|
+
fs.stat(fullname, function (err, stats) {
|
530
|
+
if (err) {
|
531
|
+
if (err.code !== 'ENOENT') {
|
532
|
+
return self.emit('error', err);
|
533
|
+
}
|
534
|
+
return createAndFlush(0);
|
535
|
+
}
|
536
|
+
|
537
|
+
if (!stats || (self.maxsize && stats.size >= self.maxsize)) {
|
538
|
+
//
|
539
|
+
// If `stats.size` is greater than the `maxsize` for
|
540
|
+
// this instance then try again
|
541
|
+
//
|
542
|
+
return self._incFile(function() {
|
543
|
+
checkFile(self._getFile());
|
544
|
+
});
|
545
|
+
}
|
546
|
+
|
547
|
+
createAndFlush(stats.size);
|
548
|
+
});
|
549
|
+
})(this._getFile());
|
550
|
+
};
|
551
|
+
|
552
|
+
|
553
|
+
File.prototype._incFile = function (callback) {
|
554
|
+
var ext = path.extname(this._basename),
|
555
|
+
basename = path.basename(this._basename, ext),
|
556
|
+
oldest,
|
557
|
+
target;
|
558
|
+
|
559
|
+
if (!this.tailable) {
|
560
|
+
this._created += 1;
|
561
|
+
this._checkMaxFilesIncrementing(ext, basename, callback);
|
562
|
+
}
|
563
|
+
else {
|
564
|
+
this._checkMaxFilesTailable(ext, basename, callback);
|
565
|
+
}
|
566
|
+
};
|
567
|
+
|
568
|
+
//
|
569
|
+
// ### @private function _getFile ()
|
570
|
+
// Gets the next filename to use for this instance
|
571
|
+
// in the case that log filesizes are being capped.
|
572
|
+
//
|
573
|
+
File.prototype._getFile = function () {
|
574
|
+
var ext = path.extname(this._basename),
|
575
|
+
basename = path.basename(this._basename, ext);
|
576
|
+
|
577
|
+
//
|
578
|
+
// Caveat emptor (indexzero): rotationFormat() was broken by design
|
579
|
+
// when combined with max files because the set of files to unlink
|
580
|
+
// is never stored.
|
581
|
+
//
|
582
|
+
return !this.tailable && this._created
|
583
|
+
? basename + (this.rotationFormat ? this.rotationFormat() : this._created) + ext
|
584
|
+
: basename + ext;
|
585
|
+
};
|
586
|
+
|
587
|
+
//
|
588
|
+
// ### @private function _checkMaxFilesIncrementing ()
|
589
|
+
// Increment the number of files created or
|
590
|
+
// checked by this instance.
|
591
|
+
//
|
592
|
+
File.prototype._checkMaxFilesIncrementing = function (ext, basename, callback) {
|
593
|
+
var oldest, target,
|
594
|
+
self = this;
|
595
|
+
|
596
|
+
if (self.zippedArchive) {
|
597
|
+
self._archive = path.join(self.dirname, basename +
|
598
|
+
((self._created === 1) ? '' : self._created-1) +
|
599
|
+
ext);
|
600
|
+
}
|
601
|
+
|
602
|
+
|
603
|
+
// Check for maxFiles option and delete file
|
604
|
+
if (!self.maxFiles || self._created < self.maxFiles) {
|
605
|
+
return callback();
|
606
|
+
}
|
607
|
+
|
608
|
+
oldest = self._created - self.maxFiles;
|
609
|
+
target = path.join(self.dirname, basename + (oldest !== 0 ? oldest : '') + ext +
|
610
|
+
(self.zippedArchive ? '.gz' : ''));
|
611
|
+
fs.unlink(target, callback);
|
612
|
+
};
|
613
|
+
|
614
|
+
//
|
615
|
+
// ### @private function _checkMaxFilesTailable ()
|
616
|
+
//
|
617
|
+
// Roll files forward based on integer, up to maxFiles.
|
618
|
+
// e.g. if base if file.log and it becomes oversized, roll
|
619
|
+
// to file1.log, and allow file.log to be re-used. If
|
620
|
+
// file is oversized again, roll file1.log to file2.log,
|
621
|
+
// roll file.log to file1.log, and so on.
|
622
|
+
File.prototype._checkMaxFilesTailable = function (ext, basename, callback) {
|
623
|
+
var tasks = [],
|
624
|
+
self = this;
|
625
|
+
|
626
|
+
if (!this.maxFiles)
|
627
|
+
return;
|
628
|
+
|
629
|
+
for (var x = this.maxFiles - 1; x > 0; x--) {
|
630
|
+
tasks.push(function (i) {
|
631
|
+
return function (cb) {
|
632
|
+
var tmppath = path.join(self.dirname, basename + (i - 1) + ext +
|
633
|
+
(self.zippedArchive ? '.gz' : ''));
|
634
|
+
fs.exists(tmppath, function (exists) {
|
635
|
+
if (!exists) {
|
636
|
+
return cb(null);
|
637
|
+
}
|
638
|
+
|
639
|
+
fs.rename(tmppath, path.join(self.dirname, basename + i + ext +
|
640
|
+
(self.zippedArchive ? '.gz' : '')), cb);
|
641
|
+
});
|
642
|
+
};
|
643
|
+
}(x));
|
644
|
+
}
|
645
|
+
|
646
|
+
if (self.zippedArchive) {
|
647
|
+
self._archive = path.join(self.dirname, basename + 1 + ext);
|
648
|
+
}
|
649
|
+
async.series(tasks, function (err) {
|
650
|
+
fs.rename(
|
651
|
+
path.join(self.dirname, basename + ext),
|
652
|
+
path.join(self.dirname, basename + 1 + ext),
|
653
|
+
callback
|
654
|
+
);
|
655
|
+
});
|
656
|
+
};
|
657
|
+
|
658
|
+
//
|
659
|
+
// ### @private function _lazyDrain ()
|
660
|
+
// Lazily attempts to emit the `logged` event when `this.stream` has
|
661
|
+
// drained. This is really just a simple mutex that only works because
|
662
|
+
// Node.js is single-threaded.
|
663
|
+
//
|
664
|
+
File.prototype._lazyDrain = function () {
|
665
|
+
var self = this;
|
666
|
+
|
667
|
+
if (!this._draining && this._stream) {
|
668
|
+
this._draining = true;
|
669
|
+
|
670
|
+
this._stream.once('drain', function () {
|
671
|
+
this._draining = false;
|
672
|
+
self.emit('logged');
|
673
|
+
});
|
674
|
+
}
|
675
|
+
};
|