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
@@ -51,6 +51,8 @@
51
51
 
52
52
 
53
53
 
54
+ ngx_int_t abort_websockets_on_process_shutdown;
55
+
54
56
  ngx_array_t *base_uris;
55
57
 
56
58
  ngx_int_t debugger;
@@ -59,6 +61,8 @@
59
61
 
60
62
  ngx_array_t *env_vars;
61
63
 
64
+ ngx_int_t force_max_concurrent_requests_per_process;
65
+
62
66
  ngx_int_t friendly_error_pages;
63
67
 
64
68
  ngx_uint_t headers_hash_bucket_size;
@@ -203,4 +203,12 @@ void generated_set_conf_part(passenger_loc_conf_t *conf) {
203
203
  conf->vary_turbocache_by_cookie.len = 0;
204
204
 
205
205
 
206
+
207
+ conf->abort_websockets_on_process_shutdown = NGX_CONF_UNSET;
208
+
209
+
210
+
211
+ conf->force_max_concurrent_requests_per_process = NGX_CONF_UNSET;
212
+
213
+
206
214
  }
@@ -264,5 +264,17 @@ int generated_merge_part(passenger_loc_conf_t *conf, passenger_loc_conf_t *prev,
264
264
  NULL);
265
265
 
266
266
 
267
+
268
+ ngx_conf_merge_value(conf->abort_websockets_on_process_shutdown,
269
+ prev->abort_websockets_on_process_shutdown,
270
+ NGX_CONF_UNSET);
271
+
272
+
273
+
274
+ ngx_conf_merge_value(conf->force_max_concurrent_requests_per_process,
275
+ prev->force_max_concurrent_requests_per_process,
276
+ NGX_CONF_UNSET);
277
+
278
+
267
279
  return 1;
268
280
  }
@@ -0,0 +1,106 @@
1
+ /*
2
+ * Phusion Passenger - https://www.phusionpassenger.com/
3
+ * Copyright (c) 2010-2015 Phusion
4
+ *
5
+ * "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
6
+ *
7
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ * of this software and associated documentation files (the "Software"), to deal
9
+ * in the Software without restriction, including without limitation the rights
10
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ * copies of the Software, and to permit persons to whom the Software is
12
+ * furnished to do so, subject to the following conditions:
13
+ *
14
+ * The above copyright notice and this permission notice shall be included in
15
+ * all copies or substantial portions of the Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
+ * THE SOFTWARE.
24
+ */
25
+
26
+ var ustReporter = global.phusion_passenger_ustReporter;
27
+
28
+ var log;
29
+ var express;
30
+
31
+ var applicationThis;
32
+
33
+ exports.initPreLoad = function() {
34
+ log = ustReporter.getPassengerLogger();
35
+ var appRoot = ustReporter.getApplicationRoot();
36
+
37
+ try {
38
+ express = require(appRoot + "/node_modules/express");
39
+ } catch (e) {
40
+ // express not present, no need to instrument.
41
+ log.debug("Not instrumenting Express (probably not used): " + e);
42
+ return;
43
+ }
44
+
45
+ try {
46
+ log.info("==== Instrumentation [Express] ==== initialize");
47
+ log.debug("hook application.init, to be the first in the use() line..");
48
+
49
+ express.application.initOrig = express.application.init;
50
+ express.application.init = function() {
51
+ log.debug("Express application.init() called, chain and then be the first to use()..");
52
+ var rval = express.application.initOrig.apply(this, arguments);
53
+
54
+ this.use(logRequest);
55
+
56
+ applicationThis = this; // store for initPostLoad use
57
+
58
+ return rval;
59
+ };
60
+
61
+ log.debug("Express tap: application.use, to be as late as possible in the use() line, but before any other error handlers..");
62
+ express.application.useOrig = express.application.use;
63
+ express.application.use = function() {
64
+ // Express recognizes error handlers by #params = 4
65
+ if (arguments[0].length == 4) {
66
+ express.application.useOrig.call(this, logException);
67
+ }
68
+
69
+ express.application.useOrig.apply(this, arguments);
70
+ }
71
+ } catch (e) {
72
+ log.error("Unable to instrument Express due to error: " + e);
73
+ }
74
+ }
75
+
76
+ exports.initPostLoad = function() {
77
+ if (!express) {
78
+ return;
79
+ }
80
+
81
+ log.debug("add final error handler..");
82
+ try {
83
+ if (applicationThis) {
84
+ express.application.useOrig.call(applicationThis, logException);
85
+ }
86
+ } catch (e) {
87
+ log.error("Unable to instrument Express error flow due to error: " + e);
88
+ }
89
+ }
90
+
91
+ function logRequest(req, res, next) {
92
+ log.verbose("==== Instrumentation [Express] ==== REQUEST [" + req.method + " " + req.url + "] attach");
93
+ ustReporter.attachToRequest(req, res, next);
94
+ }
95
+
96
+ function logException(err, req, res, next) {
97
+ // We may have multiple exception handlers in the routing chain, ensure only the first one actually logs.
98
+ if (!res.hasLoggedException) {
99
+ log.verbose("==== Instrumentation [Express] ==== EXCEPTION + TRACE FOR [" + req.url + "]");
100
+
101
+ ustReporter.logException(err.name, err.message, err.stack);
102
+
103
+ res.hasLoggedException = true;
104
+ }
105
+ next(err);
106
+ }
@@ -0,0 +1,203 @@
1
+ /*
2
+ * Phusion Passenger - https://www.phusionpassenger.com/
3
+ * Copyright (c) 2010-2015 Phusion
4
+ *
5
+ * "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
6
+ *
7
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ * of this software and associated documentation files (the "Software"), to deal
9
+ * in the Software without restriction, including without limitation the rights
10
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ * copies of the Software, and to permit persons to whom the Software is
12
+ * furnished to do so, subject to the following conditions:
13
+ *
14
+ * The above copyright notice and this permission notice shall be included in
15
+ * all copies or substantial portions of the Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
+ * THE SOFTWARE.
24
+ */
25
+
26
+ var ustReporter = global.phusion_passenger_ustReporter;
27
+
28
+ var log;
29
+ var mongodb;
30
+
31
+ // From http://docs.mongodb.org/manual/reference/method/js-collection/
32
+ var collectionMethods = [
33
+ "aggregate", "count", "copyTo", "createIndex", "dataSize", "distinct", "drop", "dropIndex", "dropIndexes",
34
+ "ensureIndex", "explain", "find", "findAndModify", "findOne", "getIndexes", "getShardDistribution", "getShardVersion",
35
+ "group", "insert", "isCapped", "mapReduce", "reIndex", "remove", "renameCollection", "save", "stats",
36
+ "storageSize", "totalSize", "totalIndexSize", "update", "validate"
37
+ ];
38
+
39
+ function instrumentCollectionMethod(origParent, functionName, newFn) {
40
+ var originalFn = origParent[functionName];
41
+
42
+ // not used yet (unwrapping N/I)
43
+ origParent["_passenger_wrapped_" + functionName] = originalFn;
44
+
45
+ origParent[functionName] = function() {
46
+ var databaseName;
47
+ var collectionName;
48
+
49
+ if (this.s) {
50
+ // Plain driver
51
+ databaseName = this.s.dbName;
52
+ collectionName = this.s.name;
53
+ } else if (this.db) {
54
+ // Mongoskin 1.4.13
55
+ databaseName = this.db.databaseName;
56
+ collectionName = this.collectionName;
57
+ } else if (this._collection_args) {
58
+ // Mongoskin driver
59
+ databaseName = this._skin_db._connect_args[0];
60
+ collectionName = this._collection_args[0];
61
+ }
62
+
63
+ return newFn.call(this, arguments, databaseName, collectionName, functionName, originalFn);
64
+ };
65
+ }
66
+
67
+ function collectionFn(origArguments, databaseName, collectionName, functionName, originalFn) {
68
+ var friendlyName = databaseName + "." + collectionName + "." + functionName + "(..)";
69
+ var query = "";
70
+ for (i = 0; i < origArguments.length; i++) {
71
+ if (typeof(origArguments[i]) != 'function') { // mongoskin
72
+ query += (i > 0 ? "," : "") + JSON.stringify(origArguments[i]);
73
+ }
74
+ }
75
+ query = "'" + databaseName + "'.collection['" + collectionName + "']." + functionName + "(" + query + ")";
76
+
77
+ var tBegin = ustReporter.nowTimestamp();
78
+ var rval = originalFn.apply(this, origArguments);
79
+ var tEnd = ustReporter.nowTimestamp();
80
+
81
+ log.verbose("==== Instrumentation [MongoDB] ==== [" + query + "] (attach to txnId " + ustReporter.getCurrentTxnId() + ")");
82
+
83
+ ustReporter.logTimedActivityMongo("mongo: " + query, tBegin, tEnd, query);
84
+
85
+ return rval;
86
+ }
87
+
88
+ exports.initPreLoad = function() {
89
+ log = ustReporter.getPassengerLogger();
90
+ var appRoot = ustReporter.getApplicationRoot();
91
+
92
+ // See if the mongodb driver is used. It can also be used through mongoskin, in which case older mongoskin
93
+ // versions will have it as part of their own node_modules.
94
+ try {
95
+ mongodb = require(appRoot + "/node_modules/mongodb");
96
+ } catch (e1) {
97
+ try {
98
+ mongodb = require(appRoot + "/node_modules/mongoskin/node_modules/mongodb");
99
+ } catch (e2) {
100
+ log.verbose("Not instrumenting MongoDB (probably not used): (default) " + e1 + ", (mongoskin) " + e2);
101
+ return;
102
+ }
103
+ }
104
+
105
+ log.info("==== Instrumentation [MongoDB] ==== initialize");
106
+
107
+ // The 1.4 mongo driver series uses a callback mechanism that breaks continuation-local-storage.
108
+ wrapRepairCLSMongo14();
109
+
110
+ // Newer mongoskin techniques break continuation-local-storage, so we need to skin the skinner there.
111
+ wrapRepairCLSMongoskinUtils(appRoot);
112
+
113
+ try {
114
+ for (i = 0; i < collectionMethods.length; i++) {
115
+ instrumentCollectionMethod(mongodb.Collection.prototype, collectionMethods[i], collectionFn);
116
+ }
117
+ } catch (e) {
118
+ log.error("Unable to instrument MongoDB due to error: " + e);
119
+ }
120
+ }
121
+
122
+ function wrapRepairCLSMongo14() {
123
+ try {
124
+ if (!mongodb.Db.prototype._executeQueryCommand || mongodb.Db.prototype._executeInsertCommand) {
125
+ log.verbose("Not using MongoDB 1.4.x, so don't need MongoDB continuation-local-storage workaround");
126
+ return;
127
+ }
128
+
129
+ mongodb.Db.prototype._passenger_wrapped__executeQueryCommand = mongodb.Db.prototype._executeQueryCommand;
130
+ mongodb.Db.prototype._executeQueryCommand = function() {
131
+ if (arguments.length > 0 && typeof(arguments[arguments.length - 1]) === 'function') {
132
+ var callback = ustReporter.getCLSWrappedCallback(arguments[arguments.length - 1]);
133
+ var newArgs = [];
134
+ for (var i = 0; i < arguments.length - 1; i++) {
135
+ newArgs.push(arguments[i]);
136
+ }
137
+ newArgs.push(callback);
138
+ this._passenger_wrapped__executeQueryCommand.apply(this, newArgs);
139
+ } else {
140
+ this._passenger_wrapped__executeQueryCommand.apply(this, arguments);
141
+ }
142
+ }
143
+
144
+ mongodb.Db.prototype._passenger_wrapped__executeInsertCommand = mongodb.Db.prototype._executeInsertCommand;
145
+ mongodb.Db.prototype._executeInsertCommand = function() {
146
+ if (arguments.length > 0 && typeof(arguments[arguments.length - 1]) === 'function') {
147
+ var callback = ustReporter.getCLSWrappedCallback(arguments[arguments.length - 1]);
148
+ var newArgs = [];
149
+ for (var i = 0; i < arguments.length - 1; i++) {
150
+ newArgs.push(arguments[i]);
151
+ }
152
+ newArgs.push(callback);
153
+ this._passenger_wrapped__executeInsertCommand.apply(this, newArgs);
154
+ } else {
155
+ this._passenger_wrapped__executeInsertCommand.apply(this, arguments);
156
+ }
157
+ }
158
+ log.verbose("Using MongoDB 1.4.x continuation-local-storage workaround");
159
+ } catch (e) {
160
+ log.error("Not using MongoDB continuation-local-storage workaround: " + e);
161
+ }
162
+ }
163
+
164
+ // Mongoskin utils creates skin (wrapper) classes and in the process introduce an emitter for supporting
165
+ // delayed open() (e.g. while the driver is still connecting).
166
+ // The emitter breaks continuation-local-storage, but since it is for top-level classes (Db, Collection, etc.)
167
+ // we can't bind it per request, so we need to bind the individual callbacks that get pushed onto it.
168
+ function wrapRepairCLSMongoskinUtils(appRoot) {
169
+ var mongoskinUtils;
170
+ try {
171
+ mongoskinUtils = require(appRoot + "/node_modules/mongoskin/lib/utils");
172
+ } catch (e) {
173
+ log.verbose("Not using mongoskin continuation-local-storage workaround (either not used, old version, or new unsupported version): " + e);
174
+ return;
175
+ }
176
+
177
+ try {
178
+ // makeSkinClass is a factory, so need a double wrap: one to get the run-time factory output (skinClass),
179
+ // and then one that hooks the actual method in that output.
180
+ mongoskinUtils._passenger_wrapped_makeSkinClass = mongoskinUtils.makeSkinClass;
181
+ mongoskinUtils.makeSkinClass = function(NativeClass, useNativeConstructor) {
182
+ var skinClass = mongoskinUtils._passenger_wrapped_makeSkinClass(NativeClass, useNativeConstructor);
183
+
184
+ skinClass.prototype._passenger_wrapped_open = skinClass.prototype.open;
185
+ skinClass.prototype.open = function(callback) {
186
+ // Finally we can bind the callback so that when the emitter calls it, the cls is mapped correctly.
187
+ return skinClass.prototype._passenger_wrapped_open.call(this, ustReporter.getCLSWrappedCallback(callback));
188
+ }
189
+
190
+ return skinClass;
191
+ }
192
+ log.verbose("Using mongoskin continuation-local-storage workaround");
193
+ } catch (e) {
194
+ log.error("Not using mongoskin continuation-local-storage workaround (probably an unsupported version): " + e);
195
+ }
196
+ }
197
+
198
+ exports.initPostLoad = function() {
199
+ //if (!mongodb) {
200
+ // return;
201
+ //}
202
+ }
203
+
@@ -0,0 +1,227 @@
1
+ /*
2
+ * Phusion Passenger - https://www.phusionpassenger.com/
3
+ * Copyright (c) 2010-2015 Phusion
4
+ *
5
+ * "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
6
+ *
7
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ * of this software and associated documentation files (the "Software"), to deal
9
+ * in the Software without restriction, including without limitation the rights
10
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ * copies of the Software, and to permit persons to whom the Software is
12
+ * furnished to do so, subject to the following conditions:
13
+ *
14
+ * The above copyright notice and this permission notice shall be included in
15
+ * all copies or substantial portions of the Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
+ * THE SOFTWARE.
24
+ */
25
+
26
+ var codify = require('vendor-copy/codify');
27
+
28
+ var reqNamespace = require('vendor-copy/continuation-local-storage').getNamespace('passenger-request-ctx');
29
+
30
+ // Assigned by init()
31
+ var ustLog;
32
+ var log;
33
+ var appRoot;
34
+
35
+ /**
36
+ * @return logger set to Passenger's loglevel. For example, log.error("") maps to Passenger loglevel 1. All mappings:
37
+ * 1: error
38
+ * 2: warn
39
+ * 3: notice
40
+ * 4: info
41
+ * 5: verbose
42
+ * 6: debug
43
+ * 7: silly
44
+ * (other levels are mapped to critical)
45
+ */
46
+ exports.getPassengerLogger = function() {
47
+ return log;
48
+ }
49
+
50
+ /**
51
+ * @return the application root path, needed for instrumenting an application's node modules.
52
+ */
53
+ exports.getApplicationRoot = function() {
54
+ return appRoot;
55
+ }
56
+
57
+ /**
58
+ * @return timestamp in microseconds to be used as the start or end timestamp for timed logging (monotonic clock, not wall clock).
59
+ */
60
+ exports.nowTimestamp = function() {
61
+ var secAndUsec = process.hrtime();
62
+ return (secAndUsec[0] * 1e6) + (secAndUsec[1] / 1e3);
63
+ }
64
+
65
+ /**
66
+ * All Activity logs will be dropped unless they are done after this method, from within an execution chain starting with the callback. So it is
67
+ * essential to call this function whenever you intercept a request, before code that might want to log can be reached. The function adds context
68
+ * to the execution chain such that future logs can be correctly appended to the currently open request log, also for modules that don't
69
+ * have access to the request object (such as database drivers).
70
+ *
71
+ * @param callback
72
+ * The "next" handler in line for processing the request. Logging will only work from this handler or within the same execution chain!
73
+ */
74
+ exports.attachToRequest = function(request, response, callback) {
75
+ try {
76
+ log.debug("ustReporter: attachToRequest(" + request.method + " " + request.url + ")");
77
+ var attachToTxnId = request.headers['!~passenger-txn-id'];
78
+ if (!attachToTxnId) {
79
+ log.warn("Dropping Union Station request log due to lack of txnId from Passenger Core (probably a temporary UstRouter failure)");
80
+ return callback();
81
+ }
82
+
83
+ reqNamespace.bindEmitter(request);
84
+ reqNamespace.bindEmitter(response);
85
+
86
+ // The Passenger core has an open transaction associated with the request, to which we can attach info from node instrumentation.
87
+ // However, logToUstTransaction() communicates async with the ustrouter, and is not guaranteed to deliver before the application response arrives
88
+ // back to the core (at which point the core will close the transaction and later additions will not be taken into account).
89
+ // That's why we intercept response.end() (from the doc: the method, response.end(), MUST be called on each response), so we can defer it
90
+ // until we are sure the ustrouter is aware of any attachments generated during the request handling.
91
+ response._passenger_wrapped_end = response.end;
92
+ response.end = function() {
93
+ return ustLog.deferIfPendingTxns(attachToTxnId, this, response._passenger_wrapped_end, arguments);
94
+ };
95
+
96
+ // Make request transaction ID available for other instrumentation modules, e.g. mongo doesn't know about requests (which is how the core passes
97
+ // txn ID).
98
+ reqNamespace.run(function() {
99
+ reqNamespace.set("attachToTxnId", attachToTxnId);
100
+ callback();
101
+ });
102
+ } catch (e) {
103
+ log.error("Dropping Union Station request log due to error:\n" + e.stack);
104
+ }
105
+ }
106
+
107
+ /**
108
+ * Log a timed block, described by activityName, with an optional message to display (e.g. in a mouseover).
109
+ */
110
+ exports.logTimedActivityGeneric = function(activityName, tBegin, tEnd, message) {
111
+ logTimedActivity(activityName, tBegin, tEnd, "generic", message ? { "message": message } : undefined);
112
+ }
113
+
114
+ /**
115
+ * Log a timed mongo database interaction block, described by activityName, with an optional query to display (e.g. in a mouseover).
116
+ */
117
+ exports.logTimedActivityMongo = function(activityName, tBegin, tEnd, query) {
118
+ logTimedActivity(activityName, tBegin, tEnd, "mongo", query ? { "query": query } : undefined);
119
+ }
120
+
121
+ /**
122
+ * Log a timed SQL database interaction block, described by activityName, with an optional query to display (e.g. in a mouseover).
123
+ */
124
+ exports.logTimedActivitySQL = function(activityName, tBegin, tEnd, query) {
125
+ logTimedActivity(activityName, tBegin, tEnd, "sql", query ? { "query": query } : undefined);
126
+ }
127
+
128
+ /**
129
+ * Internal, base for the public logTimedActivity...()
130
+ * @param activityName
131
+ * the name to display for this activity
132
+ * @param tBegin
133
+ * activity start timestamp, acquired using .nowTimestamp()
134
+ * @param tEnd
135
+ * activity end timestamp, acquired using .nowTimestamp()
136
+ * @param dataType
137
+ * the type of this activity, and the data in the dataObj; assumed to be one of "generic", "sql", "mongo", "view"
138
+ * @param dataObj
139
+ * optional; usually content for a mouseover
140
+ */
141
+ function logTimedActivity(activityName, tBegin, tEnd, dataType, dataObj) {
142
+ try {
143
+ log.debug("ustReporter: logTimedActivity(activityName: " + activityName + ")");
144
+ if (!activityName || !tBegin || !tEnd) {
145
+ log.error("ustReporter: logTimedActivity is missing name or begin/end timestamp, dropping.");
146
+ return;
147
+ }
148
+
149
+ var attachToTxnId = getCurrentTxnId();
150
+ if (!attachToTxnId) {
151
+ log.warn("Dropping Union Station timed action log due to lack of txnId to attach to " +
152
+ "(either request was not intercepted, cls context lost, or temporary UstRouter failure).\nCall stack: " + (new Error().stack));
153
+ return;
154
+ }
155
+
156
+ var uniqueTag = codify.toCode(tBegin);
157
+ var extraInfo;
158
+ if (!dataType) {
159
+ extraInfo = JSON.stringify({ "name": activityName });
160
+ } else {
161
+ extraInfo = JSON.stringify({ "name": activityName, "data_type": dataType, "data": dataObj });
162
+ }
163
+ var logBuf = [];
164
+ logBuf.push("BEGIN: " + uniqueTag + " (" + codify.toCode(tBegin) + ") " + new Buffer(extraInfo).toString('base64'));
165
+ logBuf.push("END: " + uniqueTag + " (" + codify.toCode(tEnd) + ")");
166
+ ustLog.logToUstTransaction("requests", logBuf, attachToTxnId);
167
+ } catch (e) {
168
+ log.error("Dropping Union Station timed action log due to error:\n" + e.stack);
169
+ }
170
+ }
171
+
172
+ /**
173
+ * For logging intercepted exceptions. If the exception occurred in relation to a request (i.e. within an execution chain from the attachToRequest
174
+ * callback), the exception will be associated with that request, otherwise it's sent as a standalone.
175
+ *
176
+ * @param name
177
+ * E.g. "NameError"
178
+ * @param message
179
+ * E.g. "undefined local variable or method for .."
180
+ * @param trace
181
+ * Backtrace
182
+ */
183
+ exports.logException = function(name, message, trace) {
184
+ try {
185
+ log.debug("ustReporter: logException(name: " + name + ", message: " + message + ")");
186
+ var logBuf = [];
187
+
188
+ var requestTxnId = getCurrentTxnId();
189
+ if (requestTxnId) {
190
+ logBuf.push("Request transaction ID: " + requestTxnId);
191
+ }
192
+
193
+ logBuf.push("Message: " + new Buffer(message).toString('base64'));
194
+ logBuf.push("Class: " + name);
195
+ logBuf.push("Backtrace: " + new Buffer(trace).toString('base64'));
196
+
197
+ ustLog.logToUstTransaction("exceptions", logBuf);
198
+ } catch (e) {
199
+ log.error("Dropping Union Station exception log due to error:\n" + e.stack);
200
+ }
201
+ }
202
+
203
+ /**
204
+ * Get the current request transaction id necessary to append logs to it. This is normally done automatically, but some modules break automatic attachment
205
+ * in the execution chain (implemented by continuation-local-storage). This method can be used to trace until at what point the transaction id gets
206
+ * lost, and patch that place with .getCLSWrappedCallback().
207
+ */
208
+ function getCurrentTxnId() {
209
+ return reqNamespace.get("attachToTxnId");
210
+ }
211
+ exports.getCurrentTxnId = getCurrentTxnId;
212
+
213
+ /**
214
+ * For patching callback systems that are incompatible with continuation-local-storage.
215
+ */
216
+ exports.getCLSWrappedCallback = function(origCallback) {
217
+ return reqNamespace.bind(origCallback);
218
+ }
219
+
220
+ /**
221
+ * For internal use. Called by Passenger loader, no need to call from anywhere else.
222
+ */
223
+ exports.init = function(logger, applicationRoot, ustLogger) {
224
+ log = logger;
225
+ appRoot = applicationRoot;
226
+ ustLog = ustLogger;
227
+ }