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,34 @@
1
+ /*
2
+ * transports.js: Set of all transports Winston knows about
3
+ *
4
+ * (C) 2010 Charlie Robbins
5
+ * MIT LICENCE
6
+ *
7
+ */
8
+
9
+ var fs = require('fs'),
10
+ path = require('path'),
11
+ common = require('./common');
12
+
13
+ var transports = exports;
14
+
15
+ //
16
+ // Setup all transports as lazy-loaded getters.
17
+ //
18
+ fs.readdirSync(path.join(__dirname, 'transports')).forEach(function (file) {
19
+ var transport = file.replace('.js', ''),
20
+ name = common.capitalize(transport);
21
+
22
+ if (transport === 'transport') {
23
+ return;
24
+ }
25
+ else if (~transport.indexOf('-')) {
26
+ name = transport.split('-').map(function (part) {
27
+ return common.capitalize(part);
28
+ }).join('');
29
+ }
30
+
31
+ transports.__defineGetter__(name, function () {
32
+ return require('./transports/' + transport)[name];
33
+ });
34
+ });
@@ -0,0 +1,128 @@
1
+ /*
2
+ * console.js: Transport for outputting to the console
3
+ *
4
+ * (C) 2010 Charlie Robbins
5
+ * MIT LICENCE
6
+ *
7
+ */
8
+
9
+ var events = require('events'),
10
+ util = require('util'),
11
+ common = require('../common'),
12
+ Transport = require('./transport').Transport;
13
+
14
+ //
15
+ // ### function Console (options)
16
+ // #### @options {Object} Options for this instance.
17
+ // Constructor function for the Console transport object responsible
18
+ // for persisting log messages and metadata to a terminal or TTY.
19
+ //
20
+ var Console = exports.Console = function (options) {
21
+ Transport.call(this, options);
22
+ options = options || {};
23
+
24
+ this.json = options.json || false;
25
+ this.colorize = options.colorize || false;
26
+ this.prettyPrint = options.prettyPrint || false;
27
+ this.timestamp = typeof options.timestamp !== 'undefined' ? options.timestamp : false;
28
+ this.showLevel = options.showLevel === undefined ? true : options.showLevel;
29
+ this.label = options.label || null;
30
+ this.logstash = options.logstash || false;
31
+ this.depth = options.depth || null;
32
+ this.align = options.align || false;
33
+ this.stderrLevels = setStderrLevels(options.stderrLevels, options.debugStdout);
34
+
35
+ if (this.json) {
36
+ this.stringify = options.stringify || function (obj) {
37
+ return JSON.stringify(obj, null, 2);
38
+ };
39
+ }
40
+
41
+ //
42
+ // Convert stderrLevels into an Object for faster key-lookup times than an Array.
43
+ //
44
+ // For backwards compatibility, stderrLevels defaults to ['error', 'debug']
45
+ // or ['error'] depending on whether options.debugStdout is true.
46
+ //
47
+ function setStderrLevels (levels, debugStdout) {
48
+ var defaultMsg = 'Cannot have non-string elements in stderrLevels Array';
49
+ if (debugStdout) {
50
+ if (levels) {
51
+ //
52
+ // Don't allow setting both debugStdout and stderrLevels together,
53
+ // since this could cause behaviour a programmer might not expect.
54
+ //
55
+ throw new Error('Cannot set debugStdout and stderrLevels together');
56
+ }
57
+
58
+ return common.stringArrayToSet(['error'], defaultMsg);
59
+ }
60
+
61
+ if (!levels) {
62
+ return common.stringArrayToSet(['error', 'debug'], defaultMsg);
63
+ } else if (!(Array.isArray(levels))) {
64
+ throw new Error('Cannot set stderrLevels to type other than Array');
65
+ }
66
+
67
+ return common.stringArrayToSet(levels, defaultMsg);
68
+ };
69
+ };
70
+
71
+ //
72
+ // Inherit from `winston.Transport`.
73
+ //
74
+ util.inherits(Console, Transport);
75
+
76
+ //
77
+ // Expose the name of this Transport on the prototype
78
+ //
79
+ Console.prototype.name = 'console';
80
+
81
+ //
82
+ // ### function log (level, msg, [meta], callback)
83
+ // #### @level {string} Level at which to log the message.
84
+ // #### @msg {string} Message to log
85
+ // #### @meta {Object} **Optional** Additional metadata to attach
86
+ // #### @callback {function} Continuation to respond to when complete.
87
+ // Core logging method exposed to Winston. Metadata is optional.
88
+ //
89
+ Console.prototype.log = function (level, msg, meta, callback) {
90
+ if (this.silent) {
91
+ return callback(null, true);
92
+ }
93
+
94
+ var self = this,
95
+ output;
96
+
97
+ output = common.log({
98
+ colorize: this.colorize,
99
+ json: this.json,
100
+ level: level,
101
+ message: msg,
102
+ meta: meta,
103
+ stringify: this.stringify,
104
+ timestamp: this.timestamp,
105
+ showLevel: this.showLevel,
106
+ prettyPrint: this.prettyPrint,
107
+ raw: this.raw,
108
+ label: this.label,
109
+ logstash: this.logstash,
110
+ depth: this.depth,
111
+ formatter: this.formatter,
112
+ align: this.align,
113
+ humanReadableUnhandledException: this.humanReadableUnhandledException
114
+ });
115
+
116
+ if (this.stderrLevels[level]) {
117
+ process.stderr.write(output + '\n');
118
+ } else {
119
+ process.stdout.write(output + '\n');
120
+ }
121
+
122
+ //
123
+ // Emit the `logged` event immediately because the event loop
124
+ // will not exit until `process.stdout` has drained anyway.
125
+ //
126
+ self.emit('logged');
127
+ callback(null, true);
128
+ };
@@ -0,0 +1,601 @@
1
+ /*
2
+ * daily-rotate-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
+ common = require('../common'),
14
+ Transport = require('./transport').Transport,
15
+ Stream = require('stream').Stream,
16
+ os = require('os');
17
+
18
+ //
19
+ // ### function DailyRotateFile (options)
20
+ // #### @options {Object} Options for this instance.
21
+ // Constructor function for the DailyRotateFile transport object responsible
22
+ // for persisting log messages and metadata to one or more files.
23
+ //
24
+ var DailyRotateFile = exports.DailyRotateFile = function (options) {
25
+ Transport.call(this, options);
26
+
27
+ //
28
+ // Helper function which throws an `Error` in the event
29
+ // that any of the rest of the arguments is present in `options`.
30
+ //
31
+ function throwIf (target /*, illegal... */) {
32
+ Array.prototype.slice.call(arguments, 1).forEach(function (name) {
33
+ if (options[name]) {
34
+ throw new Error('Cannot set ' + name + ' and ' + target + 'together');
35
+ }
36
+ });
37
+ }
38
+
39
+ if (options.filename || options.dirname) {
40
+ throwIf('filename or dirname', 'stream');
41
+ this._basename = this.filename = options.filename
42
+ ? path.basename(options.filename)
43
+ : 'winston.log';
44
+
45
+ this.dirname = options.dirname || path.dirname(options.filename);
46
+ this.options = options.options || { flags: 'a' };
47
+
48
+ //
49
+ // "24 bytes" is maybe a good value for logging lines.
50
+ //
51
+ this.options.highWaterMark = this.options.highWaterMark || 24;
52
+ }
53
+ else if (options.stream) {
54
+ throwIf('stream', 'filename', 'maxsize');
55
+ this._stream = options.stream;
56
+ this._stream.on('error', function(error){
57
+ self.emit('error', error);
58
+ });
59
+
60
+ //
61
+ // We need to listen for drain events when
62
+ // write() returns false. This can make node
63
+ // mad at times.
64
+ //
65
+ this._stream.setMaxListeners(Infinity);
66
+ }
67
+ else {
68
+ throw new Error('Cannot log to file without filename or stream.');
69
+ }
70
+
71
+ this.json = options.json !== false;
72
+ this.colorize = options.colorize || false;
73
+ this.maxsize = options.maxsize || null;
74
+ this.maxFiles = options.maxFiles || null;
75
+ this.label = options.label || null;
76
+ this.prettyPrint = options.prettyPrint || false;
77
+ this.showLevel = options.showLevel === undefined ? true : options.showLevel;
78
+ this.timestamp = options.timestamp != null ? options.timestamp : true;
79
+ this.datePattern = options.datePattern != null ? options.datePattern : '.yyyy-MM-dd';
80
+ this.depth = options.depth || null;
81
+ this.eol = options.eol || os.EOL;
82
+ this.maxRetries = options.maxRetries || 2;
83
+
84
+ if (this.json) {
85
+ this.stringify = options.stringify;
86
+ }
87
+
88
+ //
89
+ // Internal state variables representing the number
90
+ // of files this instance has created and the current
91
+ // size (in bytes) of the current logfile.
92
+ //
93
+ this._size = 0;
94
+ this._created = 0;
95
+ this._buffer = [];
96
+ this._draining = false;
97
+ this._failures = 0;
98
+
99
+ var now = new Date();
100
+ this._year = now.getFullYear();
101
+ this._month = now.getMonth();
102
+ this._date = now.getDate();
103
+ this._hour = now.getHours();
104
+ this._minute = now.getMinutes();
105
+
106
+ var token = /d{1,4}|m{1,4}|yy(?:yy)?|([HhM])\1?/g,
107
+ pad = function (val, len) {
108
+ val = String(val);
109
+ len = len || 2;
110
+ while (val.length < len) val = "0" + val;
111
+ return val;
112
+ };
113
+
114
+ this.getFormattedDate = function() {
115
+ var flags = {
116
+ yy: String(this._year).slice(2),
117
+ yyyy: this._year,
118
+ M: this._month + 1,
119
+ MM: pad(this._month + 1),
120
+ d: this._date,
121
+ dd: pad(this._date),
122
+ H: this._hour,
123
+ HH: pad(this._hour),
124
+ m: this._minute,
125
+ mm: pad(this._minute)
126
+ };
127
+ return this.datePattern.replace(token, function ($0) {
128
+ return $0 in flags ? flags[$0] : $0.slice(1, $0.length - 1);
129
+ });
130
+ };
131
+ };
132
+
133
+ //
134
+ // Inherit from `winston.Transport`.
135
+ //
136
+ util.inherits(DailyRotateFile, Transport);
137
+
138
+ //
139
+ // Expose the name of this Transport on the prototype
140
+ //
141
+ DailyRotateFile.prototype.name = 'dailyRotateFile';
142
+
143
+ //
144
+ // ### function log (level, msg, [meta], callback)
145
+ // #### @level {string} Level at which to log the message.
146
+ // #### @msg {string} Message to log
147
+ // #### @meta {Object} **Optional** Additional metadata to attach
148
+ // #### @callback {function} Continuation to respond to when complete.
149
+ // Core logging method exposed to Winston. Metadata is optional.
150
+ //
151
+ DailyRotateFile.prototype.log = function (level, msg, meta, callback) {
152
+ if (this.silent) {
153
+ return callback(null, true);
154
+ }
155
+
156
+ //
157
+ // If failures exceeds maxRetries then we can't access the
158
+ // stream. In this case we need to perform a noop and return
159
+ // an error.
160
+ //
161
+ if (this._failures >= this.maxRetries) {
162
+ return callback(new Error('Transport is in a failed state.'));
163
+ }
164
+
165
+ var self = this;
166
+
167
+ var output = common.log({
168
+ level: level,
169
+ message: msg,
170
+ meta: meta,
171
+ json: this.json,
172
+ colorize: this.colorize,
173
+ prettyPrint: this.prettyPrint,
174
+ timestamp: this.timestamp,
175
+ label: this.label,
176
+ stringify: this.stringify,
177
+ showLevel: this.showLevel,
178
+ depth: this.depth,
179
+ formatter: this.formatter,
180
+ humanReadableUnhandledException: this.humanReadableUnhandledException
181
+ }) + this.eol;
182
+
183
+ this._size += output.length;
184
+
185
+ if (!this.filename) {
186
+ //
187
+ // If there is no `filename` on this instance then it was configured
188
+ // with a raw `WriteableStream` instance and we should not perform any
189
+ // size restrictions.
190
+ //
191
+ this._write(output, callback);
192
+ this._lazyDrain();
193
+ }
194
+ else {
195
+ this.open(function (err) {
196
+ if (err) {
197
+ //
198
+ // If there was an error enqueue the message
199
+ //
200
+ return self._buffer.push([output, callback]);
201
+ }
202
+
203
+ self._write(output, callback);
204
+ self._lazyDrain();
205
+ });
206
+ }
207
+ };
208
+
209
+ //
210
+ // ### function _write (data, cb)
211
+ // #### @data {String|Buffer} Data to write to the instance's stream.
212
+ // #### @cb {function} Continuation to respond to when complete.
213
+ // Write to the stream, ensure execution of a callback on completion.
214
+ //
215
+ DailyRotateFile.prototype._write = function(data, callback) {
216
+ // If this is a file write stream, we could use the builtin
217
+ // callback functionality, however, the stream is not guaranteed
218
+ // to be an fs.WriteStream.
219
+ var ret = this._stream.write(data);
220
+ if (!callback) return;
221
+ if (ret === false) {
222
+ return this._stream.once('drain', function() {
223
+ callback(null, true);
224
+ });
225
+ }
226
+ callback(null, true);
227
+ };
228
+
229
+ //
230
+ // ### function query (options, callback)
231
+ // #### @options {Object} Loggly-like query options for this instance.
232
+ // #### @callback {function} Continuation to respond to when complete.
233
+ // Query the transport. Options object is optional.
234
+ //
235
+ DailyRotateFile.prototype.query = function (options, callback) {
236
+ if (typeof options === 'function') {
237
+ callback = options;
238
+ options = {};
239
+ }
240
+
241
+ // TODO when maxfilesize rotate occurs
242
+ var file = path.join(this.dirname, this._basename + this.getFormattedDate()),
243
+ options = this.normalizeQuery(options),
244
+ buff = '',
245
+ results = [],
246
+ row = 0;
247
+
248
+ var stream = fs.createReadStream(file, {
249
+ encoding: 'utf8'
250
+ });
251
+
252
+ stream.on('error', function (err) {
253
+ if (stream.readable) {
254
+ stream.destroy();
255
+ }
256
+ if (!callback) return;
257
+ return err.code !== 'ENOENT'
258
+ ? callback(err)
259
+ : callback(null, results);
260
+ });
261
+
262
+ stream.on('data', function (data) {
263
+ var data = (buff + data).split(/\n+/),
264
+ l = data.length - 1,
265
+ i = 0;
266
+
267
+ for (; i < l; i++) {
268
+ if (!options.start || row >= options.start) {
269
+ add(data[i]);
270
+ }
271
+ row++;
272
+ }
273
+
274
+ buff = data[l];
275
+ });
276
+
277
+ stream.on('close', function () {
278
+ if (buff) add(buff, true);
279
+ if (options.order === 'desc') {
280
+ results = results.reverse();
281
+ }
282
+ if (callback) callback(null, results);
283
+ });
284
+
285
+ function add(buff, attempt) {
286
+ try {
287
+ var log = JSON.parse(buff);
288
+ if (check(log)) push(log);
289
+ } catch (e) {
290
+ if (!attempt) {
291
+ stream.emit('error', e);
292
+ }
293
+ }
294
+ }
295
+
296
+ function push(log) {
297
+ if (options.rows && results.length >= options.rows) {
298
+ if (stream.readable) {
299
+ stream.destroy();
300
+ }
301
+ return;
302
+ }
303
+
304
+ if (options.fields) {
305
+ var obj = {};
306
+ options.fields.forEach(function (key) {
307
+ obj[key] = log[key];
308
+ });
309
+ log = obj;
310
+ }
311
+
312
+ results.push(log);
313
+ }
314
+
315
+ function check(log) {
316
+ if (!log) return;
317
+
318
+ if (typeof log !== 'object') return;
319
+
320
+ var time = new Date(log.timestamp);
321
+ if ((options.from && time < options.from)
322
+ || (options.until && time > options.until)) {
323
+ return;
324
+ }
325
+
326
+ return true;
327
+ }
328
+ };
329
+
330
+ //
331
+ // ### function stream (options)
332
+ // #### @options {Object} Stream options for this instance.
333
+ // Returns a log stream for this transport. Options object is optional.
334
+ //
335
+ DailyRotateFile.prototype.stream = function (options) {
336
+ var file = path.join(this.dirname, this._basename + this.getFormattedDate()),
337
+ options = options || {},
338
+ stream = new Stream;
339
+
340
+ var tail = {
341
+ file: file,
342
+ start: options.start
343
+ };
344
+
345
+ stream.destroy = common.tailFile(tail, function (err, line) {
346
+
347
+ if(err){
348
+ return stream.emit('error',err);
349
+ }
350
+
351
+ try {
352
+ stream.emit('data', line);
353
+ line = JSON.parse(line);
354
+ stream.emit('log', line);
355
+ } catch (e) {
356
+ stream.emit('error', e);
357
+ }
358
+ });
359
+
360
+ if(stream.resume){
361
+ stream.resume();
362
+ }
363
+
364
+ return stream;
365
+ };
366
+
367
+ //
368
+ // ### function open (callback)
369
+ // #### @callback {function} Continuation to respond to when complete
370
+ // Checks to see if a new file needs to be created based on the `maxsize`
371
+ // (if any) and the current size of the file used.
372
+ //
373
+ DailyRotateFile.prototype.open = function (callback) {
374
+ var now = new Date();
375
+ if (this.opening) {
376
+ //
377
+ // If we are already attempting to open the next
378
+ // available file then respond with a value indicating
379
+ // that the message should be buffered.
380
+ //
381
+ return callback(true);
382
+ }
383
+ else if (!this._stream || (this.maxsize && this._size >= this.maxsize) ||
384
+ (this._year < now.getFullYear() || this._month < now.getMonth() || this._date < now.getDate() || this._hour < now.getHours() || this._minute < now.getMinutes())) {
385
+ //
386
+ // If we dont have a stream or have exceeded our size, then create
387
+ // the next stream and respond with a value indicating that
388
+ // the message should be buffered.
389
+ //
390
+ callback(true);
391
+ return this._createStream();
392
+ }
393
+
394
+ //
395
+ // Otherwise we have a valid (and ready) stream.
396
+ //
397
+ callback();
398
+ };
399
+
400
+ //
401
+ // ### function close ()
402
+ // Closes the stream associated with this instance.
403
+ //
404
+ DailyRotateFile.prototype.close = function () {
405
+ var self = this;
406
+
407
+ if (this._stream) {
408
+ this._stream.end();
409
+ this._stream.destroySoon();
410
+
411
+ this._stream.once('drain', function () {
412
+ self.emit('flush');
413
+ self.emit('closed');
414
+ });
415
+ }
416
+ };
417
+
418
+ //
419
+ // ### function flush ()
420
+ // Flushes any buffered messages to the current `stream`
421
+ // used by this instance.
422
+ //
423
+ DailyRotateFile.prototype.flush = function () {
424
+ var self = this;
425
+
426
+ //
427
+ // Iterate over the `_buffer` of enqueued messaged
428
+ // and then write them to the newly created stream.
429
+ //
430
+ this._buffer.forEach(function (item) {
431
+ var str = item[0],
432
+ callback = item[1];
433
+
434
+ process.nextTick(function () {
435
+ self._write(str, callback);
436
+ self._size += str.length;
437
+ });
438
+ });
439
+
440
+ //
441
+ // Quickly truncate the `_buffer` once the write operations
442
+ // have been started
443
+ //
444
+ self._buffer.length = 0;
445
+
446
+ //
447
+ // When the stream has drained we have flushed
448
+ // our buffer.
449
+ //
450
+ self._stream.once('drain', function () {
451
+ self.emit('flush');
452
+ self.emit('logged');
453
+ });
454
+ };
455
+
456
+ //
457
+ // ### @private function _createStream ()
458
+ // Attempts to open the next appropriate file for this instance
459
+ // based on the common state (such as `maxsize` and `_basename`).
460
+ //
461
+ DailyRotateFile.prototype._createStream = function () {
462
+ var self = this;
463
+ this.opening = true;
464
+
465
+ (function checkFile (target) {
466
+ var fullname = path.join(self.dirname, target);
467
+
468
+ //
469
+ // Creates the `WriteStream` and then flushes any
470
+ // buffered messages.
471
+ //
472
+ function createAndFlush (size) {
473
+ if (self._stream) {
474
+ self._stream.end();
475
+ self._stream.destroySoon();
476
+ }
477
+
478
+ self._size = size;
479
+ self.filename = target;
480
+ self._stream = fs.createWriteStream(fullname, self.options);
481
+ self._stream.on('error', function(error){
482
+ if (self._failures < self.maxRetries) {
483
+ self._createStream();
484
+ self._failures++;
485
+ }
486
+ else {
487
+ self.emit('error', error);
488
+ }
489
+ });
490
+
491
+ //
492
+ // We need to listen for drain events when
493
+ // write() returns false. This can make node
494
+ // mad at times.
495
+ //
496
+ self._stream.setMaxListeners(Infinity);
497
+
498
+ //
499
+ // When the current stream has finished flushing
500
+ // then we can be sure we have finished opening
501
+ // and thus can emit the `open` event.
502
+ //
503
+ self.once('flush', function () {
504
+ self.opening = false;
505
+ self.emit('open', fullname);
506
+ });
507
+
508
+ //
509
+ // Remark: It is possible that in the time it has taken to find the
510
+ // next logfile to be written more data than `maxsize` has been buffered,
511
+ // but for sensible limits (10s - 100s of MB) this seems unlikely in less
512
+ // than one second.
513
+ //
514
+ self.flush();
515
+ }
516
+
517
+ fs.stat(fullname, function (err, stats) {
518
+ if (err) {
519
+ if (err.code !== 'ENOENT') {
520
+ return self.emit('error', err);
521
+ }
522
+
523
+ return createAndFlush(0);
524
+ }
525
+
526
+ if (!stats || (self.maxsize && stats.size >= self.maxsize)) {
527
+ //
528
+ // If `stats.size` is greater than the `maxsize` for
529
+ // this instance then try again
530
+ //
531
+ return checkFile(self._getFile(true));
532
+ }
533
+
534
+ var now = new Date();
535
+ if (self._year < now.getFullYear() || self._month < now.getMonth() || self._date < now.getDate() || self._hour < now.getHours() || self._minute < now.getMinutes()) {
536
+ self._year = now.getFullYear();
537
+ self._month = now.getMonth();
538
+ self._date = now.getDate();
539
+ self._hour = now.getHours();
540
+ self._minute = now.getMinutes();
541
+ self._created = 0;
542
+ return checkFile(self._getFile());
543
+ }
544
+
545
+ createAndFlush(stats.size);
546
+ });
547
+ })(this._getFile());
548
+ };
549
+
550
+ //
551
+ // ### @private function _getFile ()
552
+ // Gets the next filename to use for this instance
553
+ // in the case that log filesizes are being capped.
554
+ //
555
+ DailyRotateFile.prototype._getFile = function (inc) {
556
+ var self = this,
557
+ filename = this._basename + this.getFormattedDate(),
558
+ remaining;
559
+
560
+ if (inc) {
561
+ //
562
+ // Increment the number of files created or
563
+ // checked by this instance.
564
+ //
565
+ // Check for maxFiles option and delete file
566
+ if (this.maxFiles && (this._created >= (this.maxFiles - 1))) {
567
+ remaining = this._created - (this.maxFiles - 1);
568
+ if (remaining === 0) {
569
+ fs.unlinkSync(path.join(this.dirname, filename));
570
+ }
571
+ else {
572
+ fs.unlinkSync(path.join(this.dirname, filename + '.' + remaining));
573
+ }
574
+ }
575
+
576
+ this._created += 1;
577
+ }
578
+
579
+ return this._created
580
+ ? filename + '.' + this._created
581
+ : filename;
582
+ };
583
+
584
+ //
585
+ // ### @private function _lazyDrain ()
586
+ // Lazily attempts to emit the `logged` event when `this.stream` has
587
+ // drained. This is really just a simple mutex that only works because
588
+ // Node.js is single-threaded.
589
+ //
590
+ DailyRotateFile.prototype._lazyDrain = function () {
591
+ var self = this;
592
+
593
+ if (!this._draining && this._stream) {
594
+ this._draining = true;
595
+
596
+ this._stream.once('drain', function () {
597
+ this._draining = false;
598
+ self.emit('logged');
599
+ });
600
+ }
601
+ };