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.

Files changed (203) hide show
  1. checksums.yaml +8 -8
  2. checksums.yaml.gz.asc +7 -7
  3. data.tar.gz.asc +7 -7
  4. data/CHANGELOG +38 -2
  5. data/CONTRIBUTORS +3 -0
  6. data/README.md +5 -1
  7. data/bin/passenger-status +2 -7
  8. data/build/agent.rb +2 -0
  9. data/build/cxx_dependency_map.rb +1464 -162
  10. data/build/node_tests.rb +1 -1
  11. data/build/packaging.rb +1 -1
  12. data/dev/ci/run_travis.sh +1 -1
  13. data/dev/vagrant/provision.sh +1 -1
  14. data/npm-shrinkwrap.json +635 -125
  15. data/package.json +1 -1
  16. data/resources/templates/standalone/config.erb +33 -161
  17. data/resources/templates/standalone/global.erb +15 -0
  18. data/resources/templates/standalone/http.erb +40 -0
  19. data/resources/templates/standalone/mass_deployment_default_server.erb +11 -0
  20. data/resources/templates/standalone/rails_asset_pipeline.erb +22 -0
  21. data/resources/templates/standalone/server.erb +58 -0
  22. data/src/agent/Core/ApiServer.h +37 -32
  23. data/src/agent/Core/ApplicationPool/BasicGroupInfo.h +1 -1
  24. data/src/agent/Core/ApplicationPool/BasicProcessInfo.h +6 -0
  25. data/src/agent/Core/ApplicationPool/Common.h +1 -1
  26. data/src/agent/Core/ApplicationPool/Group/OutOfBandWork.cpp +1 -1
  27. data/src/agent/Core/ApplicationPool/Group/ProcessListManagement.cpp +4 -0
  28. data/src/agent/Core/ApplicationPool/Implementation.cpp +2 -2
  29. data/src/agent/Core/ApplicationPool/Options.h +18 -1
  30. data/src/agent/Core/ApplicationPool/Pool.h +1 -1
  31. data/src/agent/Core/ApplicationPool/Pool/AnalyticsCollection.cpp +6 -6
  32. data/src/agent/Core/ApplicationPool/Pool/GeneralUtils.cpp +3 -3
  33. data/src/agent/Core/ApplicationPool/Pool/InitializationAndShutdown.cpp +1 -1
  34. data/src/agent/Core/ApplicationPool/Pool/Miscellaneous.cpp +6 -0
  35. data/src/agent/Core/ApplicationPool/Process.h +6 -1
  36. data/src/agent/Core/ApplicationPool/Socket.h +9 -12
  37. data/src/agent/Core/Controller.h +422 -0
  38. data/src/agent/Core/{RequestHandler → Controller}/AppResponse.h +2 -0
  39. data/src/agent/Core/{RequestHandler → Controller}/BufferBody.cpp +27 -5
  40. data/src/agent/Core/{RequestHandler → Controller}/CheckoutSession.cpp +61 -31
  41. data/src/agent/Core/{RequestHandler → Controller}/Client.h +5 -2
  42. data/src/agent/Core/{RequestHandler → Controller}/ForwardResponse.cpp +93 -42
  43. data/src/agent/Core/{RequestHandler → Controller}/Hooks.cpp +107 -60
  44. data/src/agent/Core/Controller/Implementation.cpp +38 -0
  45. data/src/agent/Core/{RequestHandler → Controller}/InitRequest.cpp +134 -80
  46. data/src/agent/Core/Controller/InitializationAndShutdown.cpp +165 -0
  47. data/src/agent/Core/{RequestHandler/Utils.cpp → Controller/InternalUtils.cpp} +49 -32
  48. data/src/agent/Core/Controller/Miscellaneous.cpp +116 -0
  49. data/src/agent/Core/{RequestHandler → Controller}/Request.h +6 -4
  50. data/src/agent/Core/{RequestHandler → Controller}/SendRequest.cpp +205 -130
  51. data/src/agent/Core/Controller/StateInspectionAndConfiguration.cpp +161 -0
  52. data/src/agent/Core/{RequestHandler → Controller}/TurboCaching.h +3 -0
  53. data/src/agent/Core/CoreMain.cpp +62 -51
  54. data/src/agent/Core/OptionParser.h +24 -0
  55. data/src/agent/Core/ResponseCache.h +5 -5
  56. data/src/agent/Core/SpawningKit/Config.h +2 -2
  57. data/src/agent/Core/SpawningKit/SmartSpawner.h +1 -1
  58. data/src/agent/Core/UnionStation/{Core.h → Context.h} +14 -18
  59. data/src/agent/Core/UnionStation/StopwatchLog.h +3 -2
  60. data/src/agent/Core/UnionStation/Transaction.h +7 -7
  61. data/src/agent/Shared/ApiServerUtils.h +9 -1
  62. data/src/agent/UstRouter/ApiServer.h +5 -2
  63. data/src/agent/UstRouter/Controller.h +27 -9
  64. data/src/agent/UstRouter/UstRouterMain.cpp +1 -0
  65. data/src/agent/Watchdog/ApiServer.h +5 -2
  66. data/src/apache2_module/ConfigurationCommands.cpp +7 -0
  67. data/src/apache2_module/ConfigurationFields.hpp +2 -0
  68. data/src/apache2_module/ConfigurationSetters.cpp +24 -0
  69. data/src/apache2_module/CreateDirConfig.cpp +1 -0
  70. data/src/apache2_module/Hooks.cpp +6 -5
  71. data/src/apache2_module/MergeDirConfig.cpp +7 -0
  72. data/src/apache2_module/SetHeaders.cpp +5 -0
  73. data/src/cxx_supportlib/Constants.h +5 -3
  74. data/src/cxx_supportlib/SafeLibev.h +2 -1
  75. data/src/cxx_supportlib/UnionStationFilterSupport.h +2 -1
  76. data/src/cxx_supportlib/Utils/ReleaseableScopedPointer.h +70 -0
  77. data/src/cxx_supportlib/vendor-modified/boost/libs/regex/src/regex_raw_buffer.cpp +6 -6
  78. data/src/helper-scripts/node-loader.js +59 -0
  79. data/src/nginx_module/CacheLocationConfig.c +48 -0
  80. data/src/nginx_module/ConfigurationCommands.c +20 -0
  81. data/src/nginx_module/ConfigurationFields.h +4 -0
  82. data/src/nginx_module/CreateLocationConfig.c +8 -0
  83. data/src/nginx_module/MergeLocationConfig.c +12 -0
  84. data/src/nodejs_supportlib/phusion_passenger/log_express.js +106 -0
  85. data/src/nodejs_supportlib/phusion_passenger/log_mongodb.js +203 -0
  86. data/src/nodejs_supportlib/phusion_passenger/ustreporter.js +227 -0
  87. data/src/nodejs_supportlib/phusion_passenger/ustrouter_connector.js +446 -0
  88. data/src/nodejs_supportlib/vendor-copy/codify/codify.js +44 -0
  89. data/src/nodejs_supportlib/vendor-copy/codify/package.json +29 -0
  90. data/src/nodejs_supportlib/vendor-copy/continuation-local-storage/context.js +200 -0
  91. data/src/nodejs_supportlib/vendor-copy/continuation-local-storage/node_modules/async-listener/glue.js +488 -0
  92. data/src/nodejs_supportlib/vendor-copy/continuation-local-storage/node_modules/async-listener/index.js +407 -0
  93. data/src/nodejs_supportlib/vendor-copy/continuation-local-storage/node_modules/async-listener/node_modules/shimmer/index.js +90 -0
  94. data/src/nodejs_supportlib/vendor-copy/continuation-local-storage/node_modules/async-listener/node_modules/shimmer/package.json +40 -0
  95. data/src/nodejs_supportlib/vendor-copy/continuation-local-storage/node_modules/async-listener/package.json +54 -0
  96. data/src/nodejs_supportlib/vendor-copy/continuation-local-storage/node_modules/emitter-listener/listener.js +160 -0
  97. data/src/nodejs_supportlib/vendor-copy/continuation-local-storage/node_modules/emitter-listener/node_modules/shimmer/index.js +90 -0
  98. data/src/nodejs_supportlib/vendor-copy/continuation-local-storage/node_modules/emitter-listener/node_modules/shimmer/package.json +40 -0
  99. data/src/nodejs_supportlib/vendor-copy/continuation-local-storage/node_modules/emitter-listener/package.json +46 -0
  100. data/src/nodejs_supportlib/vendor-copy/continuation-local-storage/package.json +56 -0
  101. data/src/nodejs_supportlib/vendor-copy/network-byte-order/lib/index.js +102 -0
  102. data/src/nodejs_supportlib/vendor-copy/network-byte-order/package.json +51 -0
  103. data/src/nodejs_supportlib/vendor-copy/winston/LICENSE +19 -0
  104. data/src/nodejs_supportlib/vendor-copy/winston/lib/winston.js +165 -0
  105. data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/common.js +483 -0
  106. data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/config.js +62 -0
  107. data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/config/cli-config.js +35 -0
  108. data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/config/npm-config.js +27 -0
  109. data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/config/syslog-config.js +31 -0
  110. data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/container.js +127 -0
  111. data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/exception.js +56 -0
  112. data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/logger.js +701 -0
  113. data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/transports.js +34 -0
  114. data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/transports/console.js +128 -0
  115. data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/transports/daily-rotate-file.js +601 -0
  116. data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/transports/file.js +675 -0
  117. data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/transports/http.js +232 -0
  118. data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/transports/memory.js +89 -0
  119. data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/transports/transport.js +135 -0
  120. data/src/nodejs_supportlib/vendor-copy/winston/lib/winston/transports/webhook.js +146 -0
  121. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/async/LICENSE +19 -0
  122. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/async/lib/async.js +1283 -0
  123. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/async/package.json +66 -0
  124. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/async/support/sync-package-managers.js +53 -0
  125. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/MIT-LICENSE.txt +23 -0
  126. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/lib/colors.js +176 -0
  127. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/lib/custom/trap.js +45 -0
  128. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/lib/custom/zalgo.js +104 -0
  129. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/lib/extendStringPrototype.js +118 -0
  130. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/lib/index.js +12 -0
  131. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/lib/maps/america.js +12 -0
  132. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/lib/maps/rainbow.js +13 -0
  133. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/lib/maps/random.js +8 -0
  134. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/lib/maps/zebra.js +5 -0
  135. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/lib/styles.js +77 -0
  136. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/lib/system/supports-colors.js +61 -0
  137. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/package.json +35 -0
  138. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/safe.js +9 -0
  139. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/colors/themes/generic-logging.js +12 -0
  140. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/cycle/cycle.js +170 -0
  141. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/cycle/package.json +30 -0
  142. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/eyes/LICENSE +20 -0
  143. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/eyes/lib/eyes.js +236 -0
  144. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/eyes/package.json +42 -0
  145. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/isstream/LICENSE.md +11 -0
  146. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/isstream/isstream.js +27 -0
  147. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/isstream/package.json +42 -0
  148. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/pkginfo/LICENSE +19 -0
  149. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/pkginfo/lib/pkginfo.js +136 -0
  150. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/pkginfo/package.json +56 -0
  151. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/stack-trace/License +19 -0
  152. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/stack-trace/lib/stack-trace.js +111 -0
  153. data/src/nodejs_supportlib/vendor-copy/winston/node_modules/stack-trace/package.json +33 -0
  154. data/src/nodejs_supportlib/vendor-copy/winston/package.json +87 -0
  155. data/src/ruby_supportlib/phusion_passenger.rb +3 -4
  156. data/src/ruby_supportlib/phusion_passenger/admin_tools/instance.rb +19 -2
  157. data/src/ruby_supportlib/phusion_passenger/apache2/config_options.rb +8 -0
  158. data/src/ruby_supportlib/phusion_passenger/config/list_instances_command.rb +2 -6
  159. data/src/ruby_supportlib/phusion_passenger/config/reopen_logs_command.rb +13 -0
  160. data/src/ruby_supportlib/phusion_passenger/config/restart_app_command.rb +3 -0
  161. data/src/ruby_supportlib/phusion_passenger/config/utils.rb +9 -7
  162. data/src/ruby_supportlib/phusion_passenger/config/validate_install_command.rb +8 -1
  163. data/src/ruby_supportlib/phusion_passenger/constants.rb +3 -1
  164. data/src/ruby_supportlib/phusion_passenger/native_support.rb +20 -4
  165. data/src/ruby_supportlib/phusion_passenger/nginx/config_options.rb +8 -0
  166. data/src/ruby_supportlib/phusion_passenger/packaging.rb +1 -0
  167. data/src/ruby_supportlib/phusion_passenger/platform_info/apache_detector.rb +1 -1
  168. data/src/ruby_supportlib/phusion_passenger/platform_info/operating_system.rb +11 -4
  169. data/src/ruby_supportlib/phusion_passenger/rack/thread_handler_extension.rb +1 -1
  170. data/src/ruby_supportlib/phusion_passenger/standalone/config_options_list.rb +647 -0
  171. data/src/ruby_supportlib/phusion_passenger/standalone/config_utils.rb +229 -15
  172. data/src/ruby_supportlib/phusion_passenger/standalone/start_command.rb +35 -323
  173. data/src/ruby_supportlib/phusion_passenger/standalone/start_command/builtin_engine.rb +36 -12
  174. data/src/ruby_supportlib/phusion_passenger/standalone/start_command/nginx_engine.rb +123 -14
  175. data/src/ruby_supportlib/phusion_passenger/standalone/status_command.rb +32 -17
  176. data/src/ruby_supportlib/phusion_passenger/standalone/stop_command.rb +32 -21
  177. data/src/ruby_supportlib/phusion_passenger/standalone/version_command.rb +5 -5
  178. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/README.md +2 -2
  179. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/Rakefile +5 -1
  180. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core.rb +68 -24
  181. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/api.rb +9 -1
  182. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/context.rb +9 -7
  183. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/request_reporter.rb +3 -2
  184. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/request_reporter/basics.rb +8 -5
  185. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/simple_json.rb +395 -0
  186. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/transaction.rb +10 -7
  187. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/utils.rb +14 -0
  188. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/version_data.rb +2 -2
  189. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/ruby_versions.yml +4 -2
  190. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/ruby_versions.yml.example +2 -2
  191. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/ruby_versions.yml.travis +2 -2
  192. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/ruby_versions.yml.travis-with-sudo +16 -0
  193. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/Gemfile +1 -1
  194. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/Gemfile.lock +2 -2
  195. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/README.md +1 -1
  196. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/lib/union_station_hooks_rails.rb +44 -17
  197. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/lib/union_station_hooks_rails/active_support_cache_subscriber.rb +16 -7
  198. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/lib/union_station_hooks_rails/version_data.rb +2 -2
  199. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/union_station_hooks_rails.gemspec +1 -1
  200. metadata +99 -16
  201. metadata.gz.asc +7 -7
  202. data/resources/oss-binaries.phusionpassenger.com.crt +0 -248
  203. 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
+ };