passenger 3.0.2 → 3.0.3

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 (220) hide show
  1. data/NEWS +29 -0
  2. data/build/agents.rb +1 -0
  3. data/build/apache2.rb +2 -1
  4. data/build/cxx_tests.rb +7 -0
  5. data/build/rpm.rb +17 -22
  6. data/doc/cxxapi/Constants_8h_source.html +1 -1
  7. data/doc/cxxapi/Exceptions_8h_source.html +18 -4
  8. data/doc/cxxapi/Logging_8h_source.html +332 -262
  9. data/doc/cxxapi/annotated.html +1 -0
  10. data/doc/cxxapi/classes.html +4 -4
  11. data/doc/cxxapi/group__Exceptions.html +2 -0
  12. data/doc/cxxapi/hierarchy.html +1 -0
  13. data/doc/cxxapi/inherit__graph__35.map +1 -3
  14. data/doc/cxxapi/inherit__graph__35.md5 +1 -1
  15. data/doc/cxxapi/inherit__graph__35.png +0 -0
  16. data/doc/cxxapi/inherit__graph__36.map +3 -1
  17. data/doc/cxxapi/inherit__graph__36.md5 +1 -1
  18. data/doc/cxxapi/inherit__graph__36.png +0 -0
  19. data/doc/cxxapi/inherit__graph__37.map +1 -1
  20. data/doc/cxxapi/inherit__graph__37.md5 +1 -1
  21. data/doc/cxxapi/inherit__graph__37.png +0 -0
  22. data/doc/cxxapi/inherit__graph__38.map +1 -1
  23. data/doc/cxxapi/inherit__graph__38.md5 +1 -1
  24. data/doc/cxxapi/inherit__graph__38.png +0 -0
  25. data/doc/cxxapi/inherit__graph__39.map +1 -1
  26. data/doc/cxxapi/inherit__graph__39.md5 +1 -1
  27. data/doc/cxxapi/inherit__graph__39.png +0 -0
  28. data/doc/cxxapi/inherit__graph__40.map +1 -1
  29. data/doc/cxxapi/inherit__graph__40.md5 +1 -1
  30. data/doc/cxxapi/inherit__graph__40.png +0 -0
  31. data/doc/cxxapi/inherits.html +9 -6
  32. data/doc/cxxapi/namespacePassenger.html +2 -0
  33. data/doc/cxxapi/tree.html +2 -0
  34. data/doc/rdoc/classes/ConditionVariable.html +215 -0
  35. data/doc/rdoc/classes/Exception.html +120 -0
  36. data/doc/rdoc/classes/GC.html +113 -0
  37. data/doc/rdoc/classes/IO.html +221 -0
  38. data/doc/rdoc/classes/PhusionPassenger.html +397 -0
  39. data/doc/rdoc/classes/PhusionPassenger/AbstractInstaller.html +180 -0
  40. data/doc/rdoc/classes/PhusionPassenger/AbstractRequestHandler.html +647 -0
  41. data/doc/rdoc/classes/PhusionPassenger/AbstractServer.html +654 -0
  42. data/doc/rdoc/classes/PhusionPassenger/AbstractServer/InvalidPassword.html +92 -0
  43. data/doc/rdoc/classes/PhusionPassenger/AbstractServer/ServerAlreadyStarted.html +97 -0
  44. data/doc/rdoc/classes/PhusionPassenger/AbstractServer/ServerError.html +96 -0
  45. data/doc/rdoc/classes/PhusionPassenger/AbstractServer/ServerNotStarted.html +97 -0
  46. data/doc/rdoc/classes/PhusionPassenger/AbstractServer/UnknownMessage.html +96 -0
  47. data/doc/rdoc/classes/PhusionPassenger/AbstractServerCollection.html +619 -0
  48. data/doc/rdoc/classes/PhusionPassenger/AdminTools.html +142 -0
  49. data/doc/rdoc/classes/PhusionPassenger/AdminTools/MemoryStats.html +368 -0
  50. data/doc/rdoc/classes/PhusionPassenger/AdminTools/MemoryStats/Process.html +231 -0
  51. data/doc/rdoc/classes/PhusionPassenger/AdminTools/ServerInstance.html +588 -0
  52. data/doc/rdoc/classes/PhusionPassenger/AdminTools/ServerInstance/CorruptedDirectoryError.html +92 -0
  53. data/doc/rdoc/classes/PhusionPassenger/AdminTools/ServerInstance/GenerationsAbsentError.html +92 -0
  54. data/doc/rdoc/classes/PhusionPassenger/AdminTools/ServerInstance/Group.html +147 -0
  55. data/doc/rdoc/classes/PhusionPassenger/AdminTools/ServerInstance/Process.html +279 -0
  56. data/doc/rdoc/classes/PhusionPassenger/AdminTools/ServerInstance/RoleDeniedError.html +92 -0
  57. data/doc/rdoc/classes/PhusionPassenger/AdminTools/ServerInstance/StaleDirectoryError.html +92 -0
  58. data/doc/rdoc/classes/PhusionPassenger/AdminTools/ServerInstance/Stats.html +123 -0
  59. data/doc/rdoc/classes/PhusionPassenger/AdminTools/ServerInstance/UnsupportedGenerationStructureVersionError.html +92 -0
  60. data/doc/rdoc/classes/PhusionPassenger/AnalyticsLogger.html +368 -0
  61. data/doc/rdoc/classes/PhusionPassenger/AnalyticsLogger/Log.html +299 -0
  62. data/doc/rdoc/classes/PhusionPassenger/AnalyticsLogger/SharedData.html +206 -0
  63. data/doc/rdoc/classes/PhusionPassenger/AppInitError.html +155 -0
  64. data/doc/rdoc/classes/PhusionPassenger/AppProcess.html +367 -0
  65. data/doc/rdoc/classes/PhusionPassenger/ClassicRails.html +95 -0
  66. data/doc/rdoc/classes/PhusionPassenger/ClassicRails/ApplicationSpawner.html +351 -0
  67. data/doc/rdoc/classes/PhusionPassenger/ClassicRails/ApplicationSpawner/Error.html +98 -0
  68. data/doc/rdoc/classes/PhusionPassenger/ClassicRails/CGIFixed.html +200 -0
  69. data/doc/rdoc/classes/PhusionPassenger/ClassicRails/FrameworkSpawner.html +410 -0
  70. data/doc/rdoc/classes/PhusionPassenger/ClassicRails/FrameworkSpawner/Error.html +98 -0
  71. data/doc/rdoc/classes/PhusionPassenger/ClassicRails/RequestHandler.html +156 -0
  72. data/doc/rdoc/classes/PhusionPassenger/ClassicRailsExtensions.html +115 -0
  73. data/doc/rdoc/classes/PhusionPassenger/ClassicRailsExtensions/AnalyticsLogging.html +202 -0
  74. data/doc/rdoc/classes/PhusionPassenger/ConsoleTextTemplate.html +172 -0
  75. data/doc/rdoc/classes/PhusionPassenger/DebugLogging.html +273 -0
  76. data/doc/rdoc/classes/PhusionPassenger/FrameworkInitError.html +145 -0
  77. data/doc/rdoc/classes/PhusionPassenger/HTMLTemplate.html +162 -0
  78. data/doc/rdoc/classes/PhusionPassenger/InitializationError.html +141 -0
  79. data/doc/rdoc/classes/PhusionPassenger/InvalidPath.html +92 -0
  80. data/doc/rdoc/classes/PhusionPassenger/MessageChannel.html +673 -0
  81. data/doc/rdoc/classes/PhusionPassenger/MessageChannel/InvalidHashError.html +92 -0
  82. data/doc/rdoc/classes/PhusionPassenger/MessageClient.html +415 -0
  83. data/doc/rdoc/classes/PhusionPassenger/NativeSupportLoader.html +134 -0
  84. data/doc/rdoc/classes/PhusionPassenger/Packaging.html +129 -0
  85. data/doc/rdoc/classes/PhusionPassenger/PlatformInfo.html +1972 -0
  86. data/doc/rdoc/classes/PhusionPassenger/Plugin.html +237 -0
  87. data/doc/rdoc/classes/PhusionPassenger/Rack.html +91 -0
  88. data/doc/rdoc/classes/PhusionPassenger/Rack/ApplicationSpawner.html +312 -0
  89. data/doc/rdoc/classes/PhusionPassenger/Rack/ApplicationSpawner/Error.html +98 -0
  90. data/doc/rdoc/classes/PhusionPassenger/Rack/RequestHandler.html +218 -0
  91. data/doc/rdoc/classes/PhusionPassenger/Rails3Extensions.html +114 -0
  92. data/doc/rdoc/classes/PhusionPassenger/Rails3Extensions/AnalyticsLogging.html +259 -0
  93. data/doc/rdoc/classes/PhusionPassenger/Rails3Extensions/AnalyticsLogging/ACExtension.html +139 -0
  94. data/doc/rdoc/classes/PhusionPassenger/Rails3Extensions/AnalyticsLogging/ASBenchmarkableExtension.html +118 -0
  95. data/doc/rdoc/classes/PhusionPassenger/Rails3Extensions/AnalyticsLogging/ExceptionLogger.html +135 -0
  96. data/doc/rdoc/classes/PhusionPassenger/SpawnManager.html +378 -0
  97. data/doc/rdoc/classes/PhusionPassenger/Standalone.html +111 -0
  98. data/doc/rdoc/classes/PhusionPassenger/Standalone/AppFinder.html +252 -0
  99. data/doc/rdoc/classes/PhusionPassenger/Standalone/Command.html +161 -0
  100. data/doc/rdoc/classes/PhusionPassenger/Standalone/ConfigFile.html +368 -0
  101. data/doc/rdoc/classes/PhusionPassenger/Standalone/ConfigFile/DisallowedContextError.html +132 -0
  102. data/doc/rdoc/classes/PhusionPassenger/Standalone/HelpCommand.html +151 -0
  103. data/doc/rdoc/classes/PhusionPassenger/Standalone/Main.html +189 -0
  104. data/doc/rdoc/classes/PhusionPassenger/Standalone/PackageRuntimeCommand.html +177 -0
  105. data/doc/rdoc/classes/PhusionPassenger/Standalone/RuntimeInstaller.html +341 -0
  106. data/doc/rdoc/classes/PhusionPassenger/Standalone/StartCommand.html +203 -0
  107. data/doc/rdoc/classes/PhusionPassenger/Standalone/StatusCommand.html +156 -0
  108. data/doc/rdoc/classes/PhusionPassenger/Standalone/StopCommand.html +168 -0
  109. data/doc/rdoc/classes/PhusionPassenger/Standalone/Utils.html +86 -0
  110. data/doc/rdoc/classes/PhusionPassenger/Standalone/VersionCommand.html +135 -0
  111. data/doc/rdoc/classes/PhusionPassenger/UnknownError.html +125 -0
  112. data/doc/rdoc/classes/PhusionPassenger/Utils.html +1543 -0
  113. data/doc/rdoc/classes/PhusionPassenger/Utils/FileSystemWatcher.html +204 -0
  114. data/doc/rdoc/classes/PhusionPassenger/Utils/FileSystemWatcher/DirInfo.html +171 -0
  115. data/doc/rdoc/classes/PhusionPassenger/Utils/FileSystemWatcher/FileInfo.html +140 -0
  116. data/doc/rdoc/classes/PhusionPassenger/Utils/HostsFileParser.html +260 -0
  117. data/doc/rdoc/classes/PhusionPassenger/Utils/PseudoIO.html +194 -0
  118. data/doc/rdoc/classes/PhusionPassenger/Utils/RewindableInput.html +265 -0
  119. data/doc/rdoc/classes/PhusionPassenger/Utils/RewindableInput/Tempfile.html +120 -0
  120. data/doc/rdoc/classes/PhusionPassenger/Utils/UnseekableSocket.html +561 -0
  121. data/doc/rdoc/classes/PhusionPassenger/VersionNotFound.html +140 -0
  122. data/doc/rdoc/classes/PhusionPassenger/WSGI.html +89 -0
  123. data/doc/rdoc/classes/PhusionPassenger/WSGI/ApplicationSpawner.html +182 -0
  124. data/doc/rdoc/classes/Process.html +115 -0
  125. data/doc/rdoc/classes/Signal.html +139 -0
  126. data/doc/rdoc/created.rid +1 -0
  127. data/doc/rdoc/files/DEVELOPERS_TXT.html +280 -0
  128. data/doc/rdoc/files/README.html +157 -0
  129. data/doc/rdoc/files/lib/phusion_passenger/abstract_installer_rb.html +130 -0
  130. data/doc/rdoc/files/lib/phusion_passenger/abstract_request_handler_rb.html +135 -0
  131. data/doc/rdoc/files/lib/phusion_passenger/abstract_server_collection_rb.html +126 -0
  132. data/doc/rdoc/files/lib/phusion_passenger/abstract_server_rb.html +128 -0
  133. data/doc/rdoc/files/lib/phusion_passenger/admin_tools/memory_stats_rb.html +126 -0
  134. data/doc/rdoc/files/lib/phusion_passenger/admin_tools/server_instance_rb.html +132 -0
  135. data/doc/rdoc/files/lib/phusion_passenger/admin_tools_rb.html +122 -0
  136. data/doc/rdoc/files/lib/phusion_passenger/analytics_logger_rb.html +129 -0
  137. data/doc/rdoc/files/lib/phusion_passenger/app_process_rb.html +127 -0
  138. data/doc/rdoc/files/lib/phusion_passenger/classic_rails/application_spawner_rb.html +141 -0
  139. data/doc/rdoc/files/lib/phusion_passenger/classic_rails/cgi_fixed_rb.html +126 -0
  140. data/doc/rdoc/files/lib/phusion_passenger/classic_rails/framework_spawner_rb.html +146 -0
  141. data/doc/rdoc/files/lib/phusion_passenger/classic_rails/request_handler_rb.html +125 -0
  142. data/doc/rdoc/files/lib/phusion_passenger/classic_rails_extensions/init_rb.html +132 -0
  143. data/doc/rdoc/files/lib/phusion_passenger/console_text_template_rb.html +126 -0
  144. data/doc/rdoc/files/lib/phusion_passenger/constants_rb.html +122 -0
  145. data/doc/rdoc/files/lib/phusion_passenger/debug_logging_rb.html +122 -0
  146. data/doc/rdoc/files/lib/phusion_passenger/dependencies_rb.html +147 -0
  147. data/doc/rdoc/files/lib/phusion_passenger/exceptions_rb.html +122 -0
  148. data/doc/rdoc/files/lib/phusion_passenger/html_template_rb.html +127 -0
  149. data/doc/rdoc/files/lib/phusion_passenger/message_channel_rb.html +120 -0
  150. data/doc/rdoc/files/lib/phusion_passenger/message_client_rb.html +127 -0
  151. data/doc/rdoc/files/lib/phusion_passenger/native_support_rb.html +132 -0
  152. data/doc/rdoc/files/lib/phusion_passenger/packaging_rb.html +122 -0
  153. data/doc/rdoc/files/lib/phusion_passenger/platform_info/apache_rb.html +127 -0
  154. data/doc/rdoc/files/lib/phusion_passenger/platform_info/binary_compatibility_rb.html +129 -0
  155. data/doc/rdoc/files/lib/phusion_passenger/platform_info/compiler_rb.html +127 -0
  156. data/doc/rdoc/files/lib/phusion_passenger/platform_info/curl_rb.html +126 -0
  157. data/doc/rdoc/files/lib/phusion_passenger/platform_info/documentation_tools_rb.html +126 -0
  158. data/doc/rdoc/files/lib/phusion_passenger/platform_info/linux_rb.html +126 -0
  159. data/doc/rdoc/files/lib/phusion_passenger/platform_info/operating_system_rb.html +127 -0
  160. data/doc/rdoc/files/lib/phusion_passenger/platform_info/ruby_rb.html +128 -0
  161. data/doc/rdoc/files/lib/phusion_passenger/platform_info/zlib_rb.html +126 -0
  162. data/doc/rdoc/files/lib/phusion_passenger/platform_info_rb.html +122 -0
  163. data/doc/rdoc/files/lib/phusion_passenger/plugin_rb.html +127 -0
  164. data/doc/rdoc/files/lib/phusion_passenger/public_api_rb.html +127 -0
  165. data/doc/rdoc/files/lib/phusion_passenger/rack/application_spawner_rb.html +137 -0
  166. data/doc/rdoc/files/lib/phusion_passenger/rack/request_handler_rb.html +125 -0
  167. data/doc/rdoc/files/lib/phusion_passenger/rails3_extensions/init_rb.html +127 -0
  168. data/doc/rdoc/files/lib/phusion_passenger/simple_benchmarking_rb.html +122 -0
  169. data/doc/rdoc/files/lib/phusion_passenger/spawn_manager_rb.html +160 -0
  170. data/doc/rdoc/files/lib/phusion_passenger/standalone/app_finder_rb.html +127 -0
  171. data/doc/rdoc/files/lib/phusion_passenger/standalone/command_rb.html +136 -0
  172. data/doc/rdoc/files/lib/phusion_passenger/standalone/config_file_rb.html +126 -0
  173. data/doc/rdoc/files/lib/phusion_passenger/standalone/help_command_rb.html +126 -0
  174. data/doc/rdoc/files/lib/phusion_passenger/standalone/main_rb.html +126 -0
  175. data/doc/rdoc/files/lib/phusion_passenger/standalone/package_runtime_command_rb.html +127 -0
  176. data/doc/rdoc/files/lib/phusion_passenger/standalone/runtime_installer_rb.html +133 -0
  177. data/doc/rdoc/files/lib/phusion_passenger/standalone/start_command_rb.html +136 -0
  178. data/doc/rdoc/files/lib/phusion_passenger/standalone/status_command_rb.html +126 -0
  179. data/doc/rdoc/files/lib/phusion_passenger/standalone/stop_command_rb.html +126 -0
  180. data/doc/rdoc/files/lib/phusion_passenger/standalone/utils_rb.html +126 -0
  181. data/doc/rdoc/files/lib/phusion_passenger/standalone/version_command_rb.html +127 -0
  182. data/doc/rdoc/files/lib/phusion_passenger/utils/file_system_watcher_rb.html +126 -0
  183. data/doc/rdoc/files/lib/phusion_passenger/utils/hosts_file_parser_rb.html +120 -0
  184. data/doc/rdoc/files/lib/phusion_passenger/utils/rewindable_input_rb.html +100 -0
  185. data/doc/rdoc/files/lib/phusion_passenger/utils/tmpdir_rb.html +122 -0
  186. data/doc/rdoc/files/lib/phusion_passenger/utils/unseekable_socket_rb.html +126 -0
  187. data/doc/rdoc/files/lib/phusion_passenger/utils_rb.html +179 -0
  188. data/doc/rdoc/files/lib/phusion_passenger/wsgi/application_spawner_rb.html +132 -0
  189. data/doc/rdoc/fr_class_index.html +139 -0
  190. data/doc/rdoc/fr_file_index.html +108 -0
  191. data/doc/rdoc/fr_method_index.html +439 -0
  192. data/doc/rdoc/index.html +26 -0
  193. data/doc/rdoc/rdoc-style.css +187 -0
  194. data/ext/apache2/Configuration.cpp +41 -0
  195. data/ext/apache2/Configuration.hpp +19 -0
  196. data/ext/apache2/Hooks.cpp +67 -5
  197. data/ext/common/Constants.h +1 -1
  198. data/ext/common/Exceptions.h +14 -0
  199. data/ext/common/Logging.h +76 -6
  200. data/ext/common/LoggingAgent/FilterSupport.h +1317 -0
  201. data/ext/common/LoggingAgent/LoggingServer.h +93 -4
  202. data/ext/common/LoggingAgent/RemoteSender.h +5 -5
  203. data/ext/common/Utils/StrIntUtils.cpp +12 -1
  204. data/ext/common/Utils/StrIntUtils.h +2 -1
  205. data/ext/common/Utils/StringMap.h +100 -0
  206. data/ext/nginx/Configuration.c +0 -1
  207. data/ext/nginx/ContentHandler.c +33 -7
  208. data/lib/phusion_passenger.rb +2 -2
  209. data/lib/phusion_passenger/abstract_request_handler.rb +5 -0
  210. data/lib/phusion_passenger/analytics_logger.rb +77 -11
  211. data/lib/phusion_passenger/dependencies.rb +11 -1
  212. data/lib/phusion_passenger/platform_info.rb +1 -1
  213. data/lib/phusion_passenger/utils.rb +9 -1
  214. data/test/cxx/FilterSupportTest.cpp +276 -0
  215. data/test/cxx/LoggingTest.cpp +28 -0
  216. data/test/cxx/StringMapTest.cpp +70 -0
  217. data/test/integration_tests/cgi_environment_spec.rb +10 -0
  218. metadata +170 -8
  219. data/ext/common/libboost_oxt/aggregate.cpp +0 -10
  220. data/ext/common/libpassenger_common/aggregate.cpp +0 -15
data/NEWS CHANGED
@@ -1,3 +1,32 @@
1
+ Release 3.0.3
2
+ -------------
3
+
4
+ * [Nginx] Preferred Nginx version upgraded to 0.8.54
5
+ The previous preferred version was 0.8.53.
6
+ * PATH_INFO and REQUEST_URI now contain the original escaped URI
7
+ Phusion Passenger passes the URI, as reported by Apache/Nginx, to
8
+ application processes through the PATH_INFO and REQUEST_URI variables.
9
+ These variables are supposed to contain the original, unescaped URI, e.g.
10
+ /clubs/%C3%BC. Both Apache and Nginx thought that it would be a good idea
11
+ to unescape the URI before passing it to modules like Phusion Passenger,
12
+ thereby causing PATH_INFO and REQUEST_URI to contain the unescaped URI,
13
+ e.g. /clubs/ü. This causes all sorts of encoding problems. We now manually
14
+ re-escape the URI when setting PATH_INFO and REQUEST_URI. Issue #404.
15
+ * The installer no longer detects directories as potential commands
16
+ Previously the installer would look in $PATH for everything that's
17
+ executable, including directories. If one has /usr/lib in $PATH
18
+ and a directory /usr/lib/gcc exists then the installer would recognize
19
+ /usr/lib/gcc as the compiler. We now explicitly check whether the item
20
+ is also a file.
21
+ * PseudoIO now responds to #to_io
22
+ Phusion Passenger sets STDERR to a PseudoIO object in order to capture
23
+ anything written to STDERR during application startup. This breaks
24
+ some libraries which expect STDERR to respond to #to_io. This has now
25
+ been fixed. Issue #607.
26
+ * Fixed various other minor bugs
27
+ See the git commit log for details.
28
+
29
+
1
30
  Release 3.0.2
2
31
  -------------
3
32
 
@@ -47,6 +47,7 @@ dependencies = [
47
47
  'ext/common/LoggingAgent/RemoteSender.h',
48
48
  'ext/common/LoggingAgent/ChangeNotifier.h',
49
49
  'ext/common/LoggingAgent/DataStoreId.h',
50
+ 'ext/common/LoggingAgent/FilterSupport.h',
50
51
  'ext/common/ServerInstanceDir.h',
51
52
  'ext/common/Logging.h',
52
53
  'ext/common/EventedServer.h',
@@ -35,7 +35,8 @@ APACHE2_MODULE_INPUT_FILES = {
35
35
  ext/apache2/Configuration.cpp
36
36
  ext/apache2/Configuration.h
37
37
  ext/apache2/Configuration.hpp
38
- ext/common/Constants.h),
38
+ ext/common/Constants.h
39
+ ext/common/LoggingAgent/FilterSupport.h),
39
40
  APACHE2_OUTPUT_DIR + 'Bucket.o' => %w(
40
41
  ext/apache2/Bucket.cpp
41
42
  ext/apache2/Bucket.h),
@@ -134,6 +134,7 @@ TEST_CXX_OBJECTS = {
134
134
  ext/common/LoggingAgent/RemoteSender.h
135
135
  ext/common/LoggingAgent/ChangeNotifier.h
136
136
  ext/common/LoggingAgent/DataStoreId.h
137
+ ext/common/LoggingAgent/FilterSupport.h
137
138
  ext/common/Logging.h
138
139
  ext/common/Utils.h
139
140
  ext/common/EventedServer.h
@@ -172,6 +173,9 @@ TEST_CXX_OBJECTS = {
172
173
  test/cxx/SystemTimeTest.cpp
173
174
  ext/common/Utils/SystemTime.h
174
175
  ext/common/Utils/SystemTime.cpp),
176
+ 'test/cxx/FilterSupportTest.o' => %w(
177
+ test/cxx/FilterSupportTest.cpp
178
+ ext/common/LoggingAgent/FilterSupport.h),
175
179
  'test/cxx/CachedFileStatTest.o' => %w(
176
180
  test/cxx/CachedFileStatTest.cpp
177
181
  ext/common/Utils/CachedFileStat.hpp
@@ -184,6 +188,9 @@ TEST_CXX_OBJECTS = {
184
188
  test/cxx/VariantMapTest.cpp
185
189
  ext/common/MessageChannel.h
186
190
  ext/common/Utils/VariantMap.h),
191
+ 'test/cxx/StringMapTest.o' => %w(
192
+ test/cxx/StringMapTest.cpp
193
+ ext/common/Utils/StringMap.h),
187
194
  'test/cxx/ProcessMetricsCollectorTest.o' => %w(
188
195
  test/cxx/ProcessMetricsCollectorTest.cpp
189
196
  ext/common/Utils/ProcessMetricsCollector.h),
@@ -31,17 +31,8 @@ namespace :package do
31
31
  system(*args)
32
32
  end
33
33
 
34
- def create_tarball(verbosity = 0)
35
- working_dir = "/tmp/#{`whoami`.strip}-passenger-rpm-#{Process.pid}"
36
- sub_dir = "passenger-#{PhusionPassenger::VERSION_STRING}"
37
- FileUtils.rm_rf(working_dir, :verbose => verbosity > 0)
38
- begin
39
- FileUtils.mkdir_p("#{working_dir}/#{sub_dir}", :verbose => verbosity > 0)
40
- noisy_system(*(%w{rsync -ra --exclude=.git --exclude=rpm/pkg --exclude=rpm/yum-repo --exclude=*.o --exclude=*.so} + (@verbosity > 2 ? %w{-v} : []) + (@verbosity > 3 ? %w{--progress} : []) + ['.', "#{working_dir}/#{sub_dir}/."] ))
41
- noisy_system('tar', "cz#{verbosity >= 2 ? 'v' : ''}", "-C", working_dir, '-f', "#{sources_dir}/#{sub_dir}.tar.gz", sub_dir)
42
- ensure
43
- FileUtils.rm_rf("#{working_dir}", :verbose => verbosity > 0)
44
- end
34
+ def copy_tarball(verbosity = 0)
35
+ FileUtils.cp(File.join('pkg', "passenger-#{PhusionPassenger::VERSION_STRING}.tar.gz"), sources_dir, :verbose => verbosity > 0)
45
36
  end
46
37
 
47
38
  def test_setup(*args)
@@ -55,6 +46,8 @@ namespace :package do
55
46
  end
56
47
  end
57
48
 
49
+ ENV['BUILD_VERBOSITY'] = @verbosity.to_s
50
+
58
51
  result = noisy_system('./rpm/release/mocksetup-first.sh', *args)
59
52
  if !result
60
53
  # exit status 4 means that the user needs to relogin.
@@ -68,22 +61,24 @@ namespace :package do
68
61
  end
69
62
 
70
63
  desc "Package the current release into a set of RPMs"
71
- task 'rpm' => :rpm_verbosity do
64
+ task 'rpm' => [:package, :rpm_verbosity] do
72
65
  test_setup
73
- create_tarball(@verbosity)
74
- # Add a single -v for some feedback
75
- noisy_system(*(%w{./rpm/release/build.rb --single --stage-dir=pkg --extra-packages=release/mock-repo} + @build_verbosity))
66
+ copy_tarball(@verbosity)
67
+ noisy_system(*(%w{./rpm/release/build.rb --single} + ["--stage-dir=#{ENV['stage_dir'] || 'pkg'}", "--extra-packages=#{ENV['extra_packages'] || 'release/mock-repo'}"] + @build_verbosity))
76
68
  end
77
69
 
78
70
  desc "Build a Yum repository for the current release"
79
- task 'yum' => :rpm_verbosity do
71
+ task 'yum' => [:package, :rpm_verbosity] do
80
72
  test_setup(*%w{-p createrepo -p rubygem-gem2rpm})
81
- create_tarball(@verbosity)
82
- # Add a single -v for some feedback
83
- noisy_system(*(%w{./rpm/release/build.rb --stage-dir=yum-repo --extra-packages=release/mock-repo} + @build_verbosity))
84
- Dir["yum-repo/{fedora,rhel}/*/{i386,x86_64}"].each do |dir|
73
+ copy_tarball(@verbosity)
74
+ noisy_system(*(%w{./rpm/release/build.rb --include-release} + ["--stage-dir=#{ENV['stage_dir'] || 'yum-repo'}", "--extra-packages=#{ENV['extra_packages'] || 'release/mock-repo'}"] + @build_verbosity))
75
+ repo=File.expand_path("#{ENV['stage_dir'] || 'yum-repo'}", 'rpm')
76
+ Dir["#{repo}/{fedora,rhel}/*/{i386,x86_64}"].each do |dir|
85
77
  noisy_system('createrepo', dir)
86
78
  end
79
+ FileUtils.cp(Dir["rpm/doc/*.shtml"], repo, :verbose => @verbosity > 0)
80
+ FileUtils.cp('rpm/doc/example_yum_repository_htaccess', "#{repo}/.htaccess.example", :verbose => @verbosity > 0)
81
+ FileUtils.cp('rpm/release/RPM-GPG-KEY-stealthymonkeys', "#{repo}/RPM-GPG-KEY-stealthymonkeys.asc")
87
82
  end
88
83
 
89
84
  task 'rpm_verbosity' do
@@ -91,8 +86,8 @@ namespace :package do
91
86
  @verbosity = 1
92
87
  @build_verbosity = %w{-v}
93
88
  else
94
- @verbosity = ENV['verbosity'].to_i
95
- @build_verbosity = %w{-v} * (@verbosity == 0 ? 1 : @verbosity)
89
+ @verbosity = ENV['verbosity'] ? ENV['verbosity'].to_i : 1
90
+ @build_verbosity = %w{-v} * @verbosity
96
91
  end
97
92
  end
98
93
  end
@@ -51,7 +51,7 @@
51
51
  <a name="l00026"></a>00026 <span class="preprocessor"></span><span class="preprocessor">#define _PASSENGER_CONSTANTS_H_</span>
52
52
  <a name="l00027"></a>00027 <span class="preprocessor"></span>
53
53
  <a name="l00028"></a>00028 <span class="comment">/* Don&#39;t forget to update lib/phusion_passenger.rb too. */</span>
54
- <a name="l00029"></a>00029 <span class="preprocessor">#define PASSENGER_VERSION &quot;3.0.2&quot;</span>
54
+ <a name="l00029"></a>00029 <span class="preprocessor">#define PASSENGER_VERSION &quot;3.0.3&quot;</span>
55
55
  <a name="l00030"></a>00030 <span class="preprocessor"></span>
56
56
  <a name="l00031"></a>00031 <span class="preprocessor">#define FEEDBACK_FD 3</span>
57
57
  <a name="l00032"></a>00032 <span class="preprocessor"></span>
@@ -367,10 +367,24 @@
367
367
  <a name="l00342"></a>00342 <span class="keyword">virtual</span> ~<a class="code" href="classPassenger_1_1BusyException.html" title="The application pool is too busy and cannot fulfill a get() request.">BusyException</a>() <span class="keywordflow">throw</span>() {}
368
368
  <a name="l00343"></a>00343 <span class="keyword">virtual</span> <span class="keyword">const</span> <span class="keywordtype">char</span> *what() <span class="keyword">const</span> <span class="keywordflow">throw</span>() { <span class="keywordflow">return</span> msg.c_str(); }
369
369
  <a name="l00344"></a>00344 };
370
- <a name="l00345"></a>00345
371
- <a name="l00346"></a>00346 } <span class="comment">// namespace Passenger</span>
372
- <a name="l00347"></a>00347
373
- <a name="l00348"></a>00348 <span class="preprocessor">#endif </span><span class="comment">/* _PASSENGER_EXCEPTIONS_H_ */</span>
370
+ <a name="l00345"></a>00345 <span class="comment"></span>
371
+ <a name="l00346"></a>00346 <span class="comment">/**</span>
372
+ <a name="l00347"></a>00347 <span class="comment"> * A parser detected a syntax error.</span>
373
+ <a name="l00348"></a>00348 <span class="comment"> *</span>
374
+ <a name="l00349"></a>00349 <span class="comment"> * @ingroup Exceptions</span>
375
+ <a name="l00350"></a>00350 <span class="comment"> */</span>
376
+ <a name="l00351"></a><a class="code" href="classPassenger_1_1SyntaxError.html">00351</a> <span class="keyword">class </span><a class="code" href="classPassenger_1_1SyntaxError.html" title="A parser detected a syntax error.">SyntaxError</a>: <span class="keyword">public</span> oxt::tracable_exception {
377
+ <a name="l00352"></a>00352 <span class="keyword">private</span>:
378
+ <a name="l00353"></a>00353 <span class="keywordtype">string</span> msg;
379
+ <a name="l00354"></a>00354 <span class="keyword">public</span>:
380
+ <a name="l00355"></a>00355 <a class="code" href="classPassenger_1_1SyntaxError.html" title="A parser detected a syntax error.">SyntaxError</a>(<span class="keyword">const</span> <span class="keywordtype">string</span> &amp;message): msg(message) {}
381
+ <a name="l00356"></a>00356 <span class="keyword">virtual</span> ~<a class="code" href="classPassenger_1_1SyntaxError.html" title="A parser detected a syntax error.">SyntaxError</a>() <span class="keywordflow">throw</span>() {}
382
+ <a name="l00357"></a>00357 <span class="keyword">virtual</span> <span class="keyword">const</span> <span class="keywordtype">char</span> *what() <span class="keyword">const</span> <span class="keywordflow">throw</span>() { <span class="keywordflow">return</span> msg.c_str(); }
383
+ <a name="l00358"></a>00358 };
384
+ <a name="l00359"></a>00359
385
+ <a name="l00360"></a>00360 } <span class="comment">// namespace Passenger</span>
386
+ <a name="l00361"></a>00361
387
+ <a name="l00362"></a>00362 <span class="preprocessor">#endif </span><span class="comment">/* _PASSENGER_EXCEPTIONS_H_ */</span>
374
388
  </pre></div></div>
375
389
  <hr size="1"/><address style="text-align: right;"><small>Generated by&nbsp;
376
390
  <a href="http://www.doxygen.org/index.html">
@@ -454,270 +454,340 @@
454
454
  <a name="l00429"></a>00429 };
455
455
  <a name="l00430"></a>00430
456
456
  <a name="l00431"></a>00431 <span class="keyword">class </span>AnalyticsLogger {
457
- <a name="l00432"></a>00432 <span class="keyword">private</span>:
458
- <a name="l00433"></a>00433 <span class="keyword">static</span> <span class="keyword">const</span> <span class="keywordtype">int</span> RETRY_SLEEP = 200000; <span class="comment">// microseconds</span>
459
- <a name="l00434"></a>00434
460
- <a name="l00435"></a>00435 <span class="keywordtype">string</span> serverAddress;
461
- <a name="l00436"></a>00436 <span class="keywordtype">string</span> username;
462
- <a name="l00437"></a>00437 <span class="keywordtype">string</span> password;
463
- <a name="l00438"></a>00438 <span class="keywordtype">string</span> nodeName;
464
- <a name="l00439"></a>00439 RandomGenerator randomGenerator;
465
- <a name="l00440"></a>00440 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> maxConnectTries;
466
- <a name="l00441"></a>00441 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> <span class="keywordtype">long</span> reconnectTimeout;
467
- <a name="l00442"></a>00442 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> <span class="keywordtype">long</span> nextReconnectTime;
468
- <a name="l00443"></a>00443 <span class="comment"></span>
469
- <a name="l00444"></a>00444 <span class="comment"> /** @invariant sharedData != NULL */</span>
470
- <a name="l00445"></a>00445 AnalyticsLoggerSharedDataPtr sharedData;
471
- <a name="l00446"></a>00446
472
- <a name="l00447"></a>00447 <span class="keywordtype">bool</span> connected()<span class="keyword"> const </span>{
473
- <a name="l00448"></a>00448 <span class="keywordflow">return</span> sharedData-&gt;client.connected();
474
- <a name="l00449"></a>00449 }
475
- <a name="l00450"></a>00450
476
- <a name="l00451"></a>00451 <span class="keywordtype">void</span> connect() {
477
- <a name="l00452"></a>00452 TRACE_POINT();
478
- <a name="l00453"></a>00453 vector&lt;string&gt; args;
479
- <a name="l00454"></a>00454
480
- <a name="l00455"></a>00455 sharedData-&gt;client.connect(serverAddress, username, password);
481
- <a name="l00456"></a>00456 sharedData-&gt;client.write(<span class="stringliteral">&quot;init&quot;</span>, nodeName.c_str(), NULL);
482
- <a name="l00457"></a>00457 <span class="keywordflow">if</span> (!sharedData-&gt;client.read(args)) {
483
- <a name="l00458"></a>00458 <span class="keywordflow">throw</span> SystemException(<span class="stringliteral">&quot;Cannot connect to logging server&quot;</span>, ECONNREFUSED);
484
- <a name="l00459"></a>00459 } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (args.size() != 1) {
485
- <a name="l00460"></a>00460 <span class="keywordflow">throw</span> IOException(<span class="stringliteral">&quot;Logging server returned an invalid reply for the &#39;init&#39; command&quot;</span>);
486
- <a name="l00461"></a>00461 } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (args[0] == <span class="stringliteral">&quot;server shutting down&quot;</span>) {
487
- <a name="l00462"></a>00462 <span class="keywordflow">throw</span> SystemException(<span class="stringliteral">&quot;Cannot connect to server&quot;</span>, ECONNREFUSED);
488
- <a name="l00463"></a>00463 } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (args[0] != <span class="stringliteral">&quot;ok&quot;</span>) {
489
- <a name="l00464"></a>00464 <span class="keywordflow">throw</span> IOException(<span class="stringliteral">&quot;Logging server returned an invalid reply for the &#39;init&#39; command&quot;</span>);
457
+ <a name="l00432"></a>00432 <span class="keyword">private</span>:<span class="comment"></span>
458
+ <a name="l00433"></a>00433 <span class="comment"> /** A special lock type for AnalyticsLoggerSharedData that also</span>
459
+ <a name="l00434"></a>00434 <span class="comment"> * keeps a smart pointer to the data structure so that the mutex</span>
460
+ <a name="l00435"></a>00435 <span class="comment"> * is not destroyed prematurely.</span>
461
+ <a name="l00436"></a>00436 <span class="comment"> */</span>
462
+ <a name="l00437"></a>00437 <span class="keyword">struct </span>SharedDataLock {
463
+ <a name="l00438"></a>00438 AnalyticsLoggerSharedDataPtr sharedData;
464
+ <a name="l00439"></a>00439 <span class="keywordtype">bool</span> locked;
465
+ <a name="l00440"></a>00440
466
+ <a name="l00441"></a>00441 SharedDataLock(<span class="keyword">const</span> AnalyticsLoggerSharedDataPtr &amp;d)
467
+ <a name="l00442"></a>00442 : sharedData(d)
468
+ <a name="l00443"></a>00443 {
469
+ <a name="l00444"></a>00444 d-&gt;lock.lock();
470
+ <a name="l00445"></a>00445 locked = <span class="keyword">true</span>;
471
+ <a name="l00446"></a>00446 }
472
+ <a name="l00447"></a>00447
473
+ <a name="l00448"></a>00448 ~SharedDataLock() {
474
+ <a name="l00449"></a>00449 <span class="keywordflow">if</span> (locked) {
475
+ <a name="l00450"></a>00450 sharedData-&gt;lock.unlock();
476
+ <a name="l00451"></a>00451 }
477
+ <a name="l00452"></a>00452 }
478
+ <a name="l00453"></a>00453
479
+ <a name="l00454"></a>00454 <span class="keywordtype">void</span> reset(<span class="keyword">const</span> AnalyticsLoggerSharedDataPtr &amp;d, <span class="keywordtype">bool</span> lockNow = <span class="keyword">true</span>) {
480
+ <a name="l00455"></a>00455 <span class="keywordflow">if</span> (locked) {
481
+ <a name="l00456"></a>00456 sharedData-&gt;lock.unlock();
482
+ <a name="l00457"></a>00457 }
483
+ <a name="l00458"></a>00458 sharedData = d;
484
+ <a name="l00459"></a>00459 <span class="keywordflow">if</span> (lockNow) {
485
+ <a name="l00460"></a>00460 sharedData-&gt;lock.lock();
486
+ <a name="l00461"></a>00461 locked = <span class="keyword">true</span>;
487
+ <a name="l00462"></a>00462 } <span class="keywordflow">else</span> {
488
+ <a name="l00463"></a>00463 locked = <span class="keyword">false</span>;
489
+ <a name="l00464"></a>00464 }
490
490
  <a name="l00465"></a>00465 }
491
491
  <a name="l00466"></a>00466
492
- <a name="l00467"></a>00467 <span class="comment">// Upon a write() error we want to attempt to read() the error</span>
493
- <a name="l00468"></a>00468 <span class="comment">// message before closing the socket.</span>
494
- <a name="l00469"></a>00469 sharedData-&gt;client.setAutoDisconnect(<span class="keyword">false</span>);
495
- <a name="l00470"></a>00470 }
496
- <a name="l00471"></a>00471
497
- <a name="l00472"></a>00472 <span class="keywordtype">void</span> disconnect(<span class="keywordtype">bool</span> checkErrorResponse = <span class="keyword">false</span>) {
498
- <a name="l00473"></a>00473 sharedData-&gt;disconnect(checkErrorResponse);
499
- <a name="l00474"></a>00474 <span class="comment">// We create a new SharedData here so that existing AnalyticsLog</span>
500
- <a name="l00475"></a>00475 <span class="comment">// objects still refer to the old client object and don&#39;t interfere</span>
501
- <a name="l00476"></a>00476 <span class="comment">// with any newly-established connections.</span>
502
- <a name="l00477"></a>00477 sharedData.reset(<span class="keyword">new</span> AnalyticsLoggerSharedData());
503
- <a name="l00478"></a>00478 }
504
- <a name="l00479"></a>00479
505
- <a name="l00480"></a>00480 <span class="keywordtype">bool</span> isNetworkError(<span class="keywordtype">int</span> code)<span class="keyword"> const </span>{
506
- <a name="l00481"></a>00481 <span class="keywordflow">return</span> code == EPIPE || code == ECONNREFUSED || code == ECONNRESET
507
- <a name="l00482"></a>00482 || code == EHOSTUNREACH || code == ENETDOWN || code == ENETUNREACH
508
- <a name="l00483"></a>00483 || code == ETIMEDOUT;
509
- <a name="l00484"></a>00484 }
510
- <a name="l00485"></a>00485
511
- <a name="l00486"></a>00486 <span class="keyword">public</span>:
512
- <a name="l00487"></a>00487 AnalyticsLogger() { }
513
- <a name="l00488"></a>00488
514
- <a name="l00489"></a>00489 AnalyticsLogger(<span class="keyword">const</span> <span class="keywordtype">string</span> &amp;serverAddress, <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;username,
515
- <a name="l00490"></a>00490 <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;password, <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;nodeName = <span class="stringliteral">&quot;&quot;</span>)
516
- <a name="l00491"></a>00491 {
517
- <a name="l00492"></a>00492 this-&gt;serverAddress = serverAddress;
518
- <a name="l00493"></a>00493 this-&gt;username = username;
519
- <a name="l00494"></a>00494 this-&gt;password = password;
520
- <a name="l00495"></a>00495 <span class="keywordflow">if</span> (nodeName.empty()) {
521
- <a name="l00496"></a>00496 this-&gt;nodeName = <a class="code" href="namespacePassenger.html#a1d0a66b0e207c46dc6124ff3b2f331e6" title="Returns the system&amp;#39;s host name.">getHostName</a>();
522
- <a name="l00497"></a>00497 } <span class="keywordflow">else</span> {
523
- <a name="l00498"></a>00498 this-&gt;nodeName = nodeName;
524
- <a name="l00499"></a>00499 }
525
- <a name="l00500"></a>00500 <span class="keywordflow">if</span> (!serverAddress.empty()) {
526
- <a name="l00501"></a>00501 sharedData.reset(<span class="keyword">new</span> AnalyticsLoggerSharedData());
527
- <a name="l00502"></a>00502 }
528
- <a name="l00503"></a>00503 <span class="keywordflow">if</span> (isLocalSocketAddress(serverAddress)) {
529
- <a name="l00504"></a>00504 maxConnectTries = 10;
530
- <a name="l00505"></a>00505 } <span class="keywordflow">else</span> {
531
- <a name="l00506"></a>00506 maxConnectTries = 1;
532
- <a name="l00507"></a>00507 }
533
- <a name="l00508"></a>00508 maxConnectTries = 10;
534
- <a name="l00509"></a>00509 reconnectTimeout = 60 * 1000000;
535
- <a name="l00510"></a>00510 nextReconnectTime = 0;
536
- <a name="l00511"></a>00511 }
537
- <a name="l00512"></a>00512
538
- <a name="l00513"></a>00513 AnalyticsLogPtr newTransaction(<span class="keyword">const</span> <span class="keywordtype">string</span> &amp;groupName, <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;category = <span class="stringliteral">&quot;requests&quot;</span>,
539
- <a name="l00514"></a>00514 <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;unionStationKey = <span class="keywordtype">string</span>())
540
- <a name="l00515"></a>00515 {
541
- <a name="l00516"></a>00516 <span class="keywordflow">if</span> (serverAddress.empty()) {
542
- <a name="l00517"></a>00517 <span class="keywordflow">return</span> <a class="code" href="group__Support.html#ga41b6c4a82fed72531a147de0505a8396" title="Convenience shortcut for creating a shared_ptr.">ptr</a>(<span class="keyword">new</span> AnalyticsLog());
543
- <a name="l00518"></a>00518 }
544
- <a name="l00519"></a>00519
545
- <a name="l00520"></a>00520 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> <span class="keywordtype">long</span> timestamp = SystemTime::getUsec();
546
- <a name="l00521"></a>00521 <span class="keywordtype">char</span> txnId[
547
- <a name="l00522"></a>00522 2 * <span class="keyword">sizeof</span>(<span class="keywordtype">unsigned</span> int) + <span class="comment">// max hex timestamp size</span>
548
- <a name="l00523"></a>00523 11 + <span class="comment">// space for a random identifier</span>
549
- <a name="l00524"></a>00524 1 <span class="comment">// null terminator</span>
550
- <a name="l00525"></a>00525 ];
551
- <a name="l00526"></a>00526 <span class="keywordtype">char</span> *end;
552
- <a name="l00527"></a>00527 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> timestampSize;
553
- <a name="l00528"></a>00528 <span class="keywordtype">char</span> timestampStr[2 * <span class="keyword">sizeof</span>(<span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> long) + 1];
554
- <a name="l00529"></a>00529
555
- <a name="l00530"></a>00530 <span class="comment">// &quot;[timestamp]&quot;</span>
556
- <a name="l00531"></a>00531 <span class="comment">// Our timestamp is like a Unix timestamp but with minutes</span>
557
- <a name="l00532"></a>00532 <span class="comment">// resolution instead of seconds. 32 bits will last us for</span>
558
- <a name="l00533"></a>00533 <span class="comment">// about 8000 years.</span>
559
- <a name="l00534"></a>00534 timestampSize = integerToHexatri&lt;unsigned int&gt;(timestamp / 1000000 / 60,
560
- <a name="l00535"></a>00535 txnId);
561
- <a name="l00536"></a>00536 end = txnId + timestampSize;
562
- <a name="l00537"></a>00537
563
- <a name="l00538"></a>00538 <span class="comment">// &quot;[timestamp]-&quot;</span>
564
- <a name="l00539"></a>00539 *end = <span class="charliteral">&#39;-&#39;</span>;
565
- <a name="l00540"></a>00540 end++;
566
- <a name="l00541"></a>00541
567
- <a name="l00542"></a>00542 <span class="comment">// &quot;[timestamp]-[random id]&quot;</span>
568
- <a name="l00543"></a>00543 randomGenerator.generateAsciiString(end, 11);
569
- <a name="l00544"></a>00544 end += 11;
570
- <a name="l00545"></a>00545 *end = <span class="charliteral">&#39;\0&#39;</span>;
571
- <a name="l00546"></a>00546
572
- <a name="l00547"></a>00547 integerToHexatri&lt;unsigned long long&gt;(timestamp, timestampStr);
573
- <a name="l00548"></a>00548
574
- <a name="l00549"></a>00549 lock_guard&lt;boost::mutex&gt; l(sharedData-&gt;lock);
575
- <a name="l00550"></a>00550
576
- <a name="l00551"></a>00551 <span class="keywordflow">if</span> (SystemTime::getUsec() &gt;= nextReconnectTime) {
577
- <a name="l00552"></a>00552 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> tryCount = 0;
578
- <a name="l00553"></a>00553
579
- <a name="l00554"></a>00554 <span class="keywordflow">while</span> (tryCount &lt; maxConnectTries) {
580
- <a name="l00555"></a>00555 <span class="keywordflow">try</span> {
581
- <a name="l00556"></a>00556 <span class="keywordflow">if</span> (!connected()) {
582
- <a name="l00557"></a>00557 TRACE_POINT();
583
- <a name="l00558"></a>00558 connect();
584
- <a name="l00559"></a>00559 }
585
- <a name="l00560"></a>00560 sharedData-&gt;client.write(<span class="stringliteral">&quot;openTransaction&quot;</span>,
586
- <a name="l00561"></a>00561 txnId,
587
- <a name="l00562"></a>00562 groupName.c_str(),
588
- <a name="l00563"></a>00563 <span class="stringliteral">&quot;&quot;</span>,
589
- <a name="l00564"></a>00564 category.c_str(),
590
- <a name="l00565"></a>00565 timestampStr,
591
- <a name="l00566"></a>00566 unionStationKey.c_str(),
592
- <a name="l00567"></a>00567 <span class="stringliteral">&quot;true&quot;</span>,
593
- <a name="l00568"></a>00568 NULL);
594
- <a name="l00569"></a>00569 <span class="keywordflow">return</span> <a class="code" href="group__Support.html#ga41b6c4a82fed72531a147de0505a8396" title="Convenience shortcut for creating a shared_ptr.">ptr</a>(<span class="keyword">new</span> AnalyticsLog(sharedData,
595
- <a name="l00570"></a>00570 <span class="keywordtype">string</span>(txnId, end - txnId),
596
- <a name="l00571"></a>00571 groupName, category,
597
- <a name="l00572"></a>00572 unionStationKey));
598
- <a name="l00573"></a>00573 } <span class="keywordflow">catch</span> (<span class="keyword">const</span> SystemException &amp;e) {
599
- <a name="l00574"></a>00574 TRACE_POINT();
600
- <a name="l00575"></a>00575 <span class="keywordflow">if</span> (e.code() == ENOENT || isNetworkError(e.code())) {
601
- <a name="l00576"></a>00576 tryCount++;
602
- <a name="l00577"></a>00577 disconnect(<span class="keyword">true</span>);
603
- <a name="l00578"></a>00578 <span class="keywordflow">if</span> (tryCount &lt; maxConnectTries) {
604
- <a name="l00579"></a>00579 syscalls::usleep(RETRY_SLEEP);
605
- <a name="l00580"></a>00580 }
606
- <a name="l00581"></a>00581 } <span class="keywordflow">else</span> {
607
- <a name="l00582"></a>00582 disconnect();
608
- <a name="l00583"></a>00583 <span class="keywordflow">throw</span>;
609
- <a name="l00584"></a>00584 }
610
- <a name="l00585"></a>00585 }
611
- <a name="l00586"></a>00586
612
- <a name="l00587"></a>00587 <span class="comment">// Failed to connect.</span>
613
- <a name="l00588"></a>00588 P_WARN(<span class="stringliteral">&quot;Cannot connect to the logging agent (&quot;</span> &lt;&lt; serverAddress &lt;&lt; <span class="stringliteral">&quot;); &quot;</span> &lt;&lt;
614
- <a name="l00589"></a>00589 <span class="stringliteral">&quot;retrying in &quot;</span> &lt;&lt; reconnectTimeout / 1000000 &lt;&lt; <span class="stringliteral">&quot; seconds.&quot;</span>);
615
- <a name="l00590"></a>00590 nextReconnectTime = SystemTime::getUsec() + reconnectTimeout;
616
- <a name="l00591"></a>00591 }
617
- <a name="l00592"></a>00592 }
618
- <a name="l00593"></a>00593 <span class="keywordflow">return</span> <a class="code" href="group__Support.html#ga41b6c4a82fed72531a147de0505a8396" title="Convenience shortcut for creating a shared_ptr.">ptr</a>(<span class="keyword">new</span> AnalyticsLog());
619
- <a name="l00594"></a>00594 }
620
- <a name="l00595"></a>00595
621
- <a name="l00596"></a>00596 AnalyticsLogPtr continueTransaction(<span class="keyword">const</span> <span class="keywordtype">string</span> &amp;txnId, <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;groupName,
622
- <a name="l00597"></a>00597 <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;category = <span class="stringliteral">&quot;requests&quot;</span>, <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;unionStationKey = <span class="keywordtype">string</span>())
623
- <a name="l00598"></a>00598 {
624
- <a name="l00599"></a>00599 <span class="keywordflow">if</span> (serverAddress.empty() || txnId.empty()) {
625
- <a name="l00600"></a>00600 <span class="keywordflow">return</span> <a class="code" href="group__Support.html#ga41b6c4a82fed72531a147de0505a8396" title="Convenience shortcut for creating a shared_ptr.">ptr</a>(<span class="keyword">new</span> AnalyticsLog());
626
- <a name="l00601"></a>00601 }
627
- <a name="l00602"></a>00602
628
- <a name="l00603"></a>00603 <span class="keywordtype">char</span> timestampStr[2 * <span class="keyword">sizeof</span>(<span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> long) + 1];
629
- <a name="l00604"></a>00604 integerToHexatri&lt;unsigned long long&gt;(SystemTime::getUsec(), timestampStr);
630
- <a name="l00605"></a>00605
631
- <a name="l00606"></a>00606 lock_guard&lt;boost::mutex&gt; l(sharedData-&gt;lock);
632
- <a name="l00607"></a>00607
633
- <a name="l00608"></a>00608 <span class="keywordflow">if</span> (SystemTime::getUsec() &gt;= nextReconnectTime) {
634
- <a name="l00609"></a>00609 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> tryCount = 0;
635
- <a name="l00610"></a>00610
636
- <a name="l00611"></a>00611 <span class="keywordflow">while</span> (tryCount &lt; maxConnectTries) {
637
- <a name="l00612"></a>00612 <span class="keywordflow">try</span> {
638
- <a name="l00613"></a>00613 <span class="keywordflow">if</span> (!connected()) {
639
- <a name="l00614"></a>00614 TRACE_POINT();
640
- <a name="l00615"></a>00615 connect();
641
- <a name="l00616"></a>00616 }
642
- <a name="l00617"></a>00617 sharedData-&gt;client.write(<span class="stringliteral">&quot;openTransaction&quot;</span>,
643
- <a name="l00618"></a>00618 txnId.c_str(),
644
- <a name="l00619"></a>00619 groupName.c_str(),
645
- <a name="l00620"></a>00620 <span class="stringliteral">&quot;&quot;</span>,
646
- <a name="l00621"></a>00621 category.c_str(),
647
- <a name="l00622"></a>00622 timestampStr,
648
- <a name="l00623"></a>00623 unionStationKey.c_str(),
649
- <a name="l00624"></a>00624 <span class="stringliteral">&quot;true&quot;</span>,
650
- <a name="l00625"></a>00625 NULL);
651
- <a name="l00626"></a>00626 <span class="keywordflow">return</span> <a class="code" href="group__Support.html#ga41b6c4a82fed72531a147de0505a8396" title="Convenience shortcut for creating a shared_ptr.">ptr</a>(<span class="keyword">new</span> AnalyticsLog(sharedData,
652
- <a name="l00627"></a>00627 txnId, groupName, category,
653
- <a name="l00628"></a>00628 unionStationKey));
654
- <a name="l00629"></a>00629 } <span class="keywordflow">catch</span> (<span class="keyword">const</span> SystemException &amp;e) {
655
- <a name="l00630"></a>00630 TRACE_POINT();
656
- <a name="l00631"></a>00631 <span class="keywordflow">if</span> (e.code() == EPIPE || isNetworkError(e.code())) {
657
- <a name="l00632"></a>00632 tryCount++;
658
- <a name="l00633"></a>00633 disconnect(<span class="keyword">true</span>);
659
- <a name="l00634"></a>00634 <span class="keywordflow">if</span> (tryCount &lt; maxConnectTries) {
660
- <a name="l00635"></a>00635 syscalls::usleep(RETRY_SLEEP);
661
- <a name="l00636"></a>00636 }
662
- <a name="l00637"></a>00637 } <span class="keywordflow">else</span> {
663
- <a name="l00638"></a>00638 disconnect();
664
- <a name="l00639"></a>00639 <span class="keywordflow">throw</span>;
665
- <a name="l00640"></a>00640 }
666
- <a name="l00641"></a>00641 }
667
- <a name="l00642"></a>00642 }
668
- <a name="l00643"></a>00643
669
- <a name="l00644"></a>00644 <span class="comment">// Failed to connect.</span>
670
- <a name="l00645"></a>00645 P_WARN(<span class="stringliteral">&quot;Cannot connect to the logging agent (&quot;</span> &lt;&lt; serverAddress &lt;&lt; <span class="stringliteral">&quot;); &quot;</span> &lt;&lt;
671
- <a name="l00646"></a>00646 <span class="stringliteral">&quot;retrying in &quot;</span> &lt;&lt; reconnectTimeout / 1000000 &lt;&lt; <span class="stringliteral">&quot; seconds.&quot;</span>);
672
- <a name="l00647"></a>00647 nextReconnectTime = SystemTime::getUsec() + reconnectTimeout;
673
- <a name="l00648"></a>00648 }
674
- <a name="l00649"></a>00649 <span class="keywordflow">return</span> <a class="code" href="group__Support.html#ga41b6c4a82fed72531a147de0505a8396" title="Convenience shortcut for creating a shared_ptr.">ptr</a>(<span class="keyword">new</span> AnalyticsLog());
675
- <a name="l00650"></a>00650 }
676
- <a name="l00651"></a>00651
677
- <a name="l00652"></a>00652 <span class="keywordtype">void</span> setMaxConnectTries(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> value) {
678
- <a name="l00653"></a>00653 lock_guard&lt;boost::mutex&gt; l(sharedData-&gt;lock);
679
- <a name="l00654"></a>00654 maxConnectTries = value;
680
- <a name="l00655"></a>00655 }
681
- <a name="l00656"></a>00656
682
- <a name="l00657"></a>00657 <span class="keywordtype">void</span> setReconnectTimeout(<span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> <span class="keywordtype">long</span> usec) {
683
- <a name="l00658"></a>00658 lock_guard&lt;boost::mutex&gt; l(sharedData-&gt;lock);
684
- <a name="l00659"></a>00659 reconnectTimeout = usec;
685
- <a name="l00660"></a>00660 }
686
- <a name="l00661"></a>00661
687
- <a name="l00662"></a>00662 <span class="keywordtype">bool</span> isNull()<span class="keyword"> const </span>{
688
- <a name="l00663"></a>00663 <span class="keywordflow">return</span> serverAddress.empty();
689
- <a name="l00664"></a>00664 }
690
- <a name="l00665"></a>00665
691
- <a name="l00666"></a>00666 <span class="keywordtype">string</span> getAddress()<span class="keyword"> const </span>{
692
- <a name="l00667"></a>00667 <span class="keywordflow">return</span> serverAddress;
693
- <a name="l00668"></a>00668 }
694
- <a name="l00669"></a>00669
695
- <a name="l00670"></a>00670 <span class="keywordtype">string</span> getUsername()<span class="keyword"> const </span>{
696
- <a name="l00671"></a>00671 <span class="keywordflow">return</span> username;
697
- <a name="l00672"></a>00672 }
698
- <a name="l00673"></a>00673
699
- <a name="l00674"></a>00674 <span class="keywordtype">string</span> getPassword()<span class="keyword"> const </span>{
700
- <a name="l00675"></a>00675 <span class="keywordflow">return</span> password;
701
- <a name="l00676"></a>00676 }
702
- <a name="l00677"></a>00677
703
- <a name="l00678"></a>00678 FileDescriptor getConnection()<span class="keyword"> const </span>{
704
- <a name="l00679"></a>00679 <span class="keywordflow">return</span> sharedData-&gt;client.getConnection();
705
- <a name="l00680"></a>00680 }
706
- <a name="l00681"></a>00681 <span class="comment"></span>
707
- <a name="l00682"></a>00682 <span class="comment"> /**</span>
708
- <a name="l00683"></a>00683 <span class="comment"> * @post !result.empty()</span>
709
- <a name="l00684"></a>00684 <span class="comment"> */</span>
710
- <a name="l00685"></a>00685 <span class="keywordtype">string</span> getNodeName()<span class="keyword"> const </span>{
711
- <a name="l00686"></a>00686 <span class="keywordflow">return</span> nodeName;
712
- <a name="l00687"></a>00687 }
713
- <a name="l00688"></a>00688 };
714
- <a name="l00689"></a>00689
715
- <a name="l00690"></a>00690 <span class="keyword">typedef</span> shared_ptr&lt;AnalyticsLogger&gt; AnalyticsLoggerPtr;
716
- <a name="l00691"></a>00691
717
- <a name="l00692"></a>00692 } <span class="comment">// namespace Passenger</span>
718
- <a name="l00693"></a>00693
719
- <a name="l00694"></a>00694 <span class="preprocessor">#endif </span><span class="comment">/* _PASSENGER_LOGGING_H_ */</span>
720
- <a name="l00695"></a>00695
492
+ <a name="l00467"></a>00467 <span class="keywordtype">void</span> lock() {
493
+ <a name="l00468"></a>00468 assert(!locked);
494
+ <a name="l00469"></a>00469 sharedData-&gt;lock.lock();
495
+ <a name="l00470"></a>00470 locked = <span class="keyword">true</span>;
496
+ <a name="l00471"></a>00471 }
497
+ <a name="l00472"></a>00472 };
498
+ <a name="l00473"></a>00473
499
+ <a name="l00474"></a>00474 <span class="keyword">static</span> <span class="keyword">const</span> <span class="keywordtype">int</span> RETRY_SLEEP = 200000; <span class="comment">// microseconds</span>
500
+ <a name="l00475"></a>00475
501
+ <a name="l00476"></a>00476 <span class="keywordtype">string</span> serverAddress;
502
+ <a name="l00477"></a>00477 <span class="keywordtype">string</span> username;
503
+ <a name="l00478"></a>00478 <span class="keywordtype">string</span> password;
504
+ <a name="l00479"></a>00479 <span class="keywordtype">string</span> nodeName;
505
+ <a name="l00480"></a>00480 RandomGenerator randomGenerator;
506
+ <a name="l00481"></a>00481 <span class="comment"></span>
507
+ <a name="l00482"></a>00482 <span class="comment"> /** Lock protecting the fields that follow, but not the contents of the shared data. */</span>
508
+ <a name="l00483"></a>00483 <span class="keyword">mutable</span> boost::mutex lock;
509
+ <a name="l00484"></a>00484
510
+ <a name="l00485"></a>00485 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> maxConnectTries;
511
+ <a name="l00486"></a>00486 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> <span class="keywordtype">long</span> reconnectTimeout;
512
+ <a name="l00487"></a>00487 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> <span class="keywordtype">long</span> nextReconnectTime;<span class="comment"></span>
513
+ <a name="l00488"></a>00488 <span class="comment"> /** @invariant sharedData != NULL */</span>
514
+ <a name="l00489"></a>00489 AnalyticsLoggerSharedDataPtr sharedData;
515
+ <a name="l00490"></a>00490
516
+ <a name="l00491"></a>00491 <span class="keywordtype">bool</span> connected()<span class="keyword"> const </span>{
517
+ <a name="l00492"></a>00492 <span class="keywordflow">return</span> sharedData-&gt;client.connected();
518
+ <a name="l00493"></a>00493 }
519
+ <a name="l00494"></a>00494
520
+ <a name="l00495"></a>00495 <span class="keywordtype">void</span> connect() {
521
+ <a name="l00496"></a>00496 TRACE_POINT();
522
+ <a name="l00497"></a>00497 vector&lt;string&gt; args;
523
+ <a name="l00498"></a>00498
524
+ <a name="l00499"></a>00499 sharedData-&gt;client.connect(serverAddress, username, password);
525
+ <a name="l00500"></a>00500 sharedData-&gt;client.write(<span class="stringliteral">&quot;init&quot;</span>, nodeName.c_str(), NULL);
526
+ <a name="l00501"></a>00501 <span class="keywordflow">if</span> (!sharedData-&gt;client.read(args)) {
527
+ <a name="l00502"></a>00502 <span class="keywordflow">throw</span> SystemException(<span class="stringliteral">&quot;Cannot connect to logging server&quot;</span>, ECONNREFUSED);
528
+ <a name="l00503"></a>00503 } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (args.size() != 1) {
529
+ <a name="l00504"></a>00504 <span class="keywordflow">throw</span> IOException(<span class="stringliteral">&quot;Logging server returned an invalid reply for the &#39;init&#39; command&quot;</span>);
530
+ <a name="l00505"></a>00505 } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (args[0] == <span class="stringliteral">&quot;server shutting down&quot;</span>) {
531
+ <a name="l00506"></a>00506 <span class="keywordflow">throw</span> SystemException(<span class="stringliteral">&quot;Cannot connect to server&quot;</span>, ECONNREFUSED);
532
+ <a name="l00507"></a>00507 } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (args[0] != <span class="stringliteral">&quot;ok&quot;</span>) {
533
+ <a name="l00508"></a>00508 <span class="keywordflow">throw</span> IOException(<span class="stringliteral">&quot;Logging server returned an invalid reply for the &#39;init&#39; command&quot;</span>);
534
+ <a name="l00509"></a>00509 }
535
+ <a name="l00510"></a>00510
536
+ <a name="l00511"></a>00511 <span class="comment">// Upon a write() error we want to attempt to read() the error</span>
537
+ <a name="l00512"></a>00512 <span class="comment">// message before closing the socket.</span>
538
+ <a name="l00513"></a>00513 sharedData-&gt;client.setAutoDisconnect(<span class="keyword">false</span>);
539
+ <a name="l00514"></a>00514 }
540
+ <a name="l00515"></a>00515
541
+ <a name="l00516"></a>00516 <span class="keywordtype">void</span> disconnect(<span class="keywordtype">bool</span> checkErrorResponse = <span class="keyword">false</span>) {
542
+ <a name="l00517"></a>00517 sharedData-&gt;disconnect(checkErrorResponse);
543
+ <a name="l00518"></a>00518 <span class="comment">// We create a new SharedData here so that existing AnalyticsLog</span>
544
+ <a name="l00519"></a>00519 <span class="comment">// objects still refer to the old client object and don&#39;t interfere</span>
545
+ <a name="l00520"></a>00520 <span class="comment">// with any newly-established connections.</span>
546
+ <a name="l00521"></a>00521 sharedData.reset(<span class="keyword">new</span> AnalyticsLoggerSharedData());
547
+ <a name="l00522"></a>00522 }
548
+ <a name="l00523"></a>00523
549
+ <a name="l00524"></a>00524 <span class="keywordtype">bool</span> isNetworkError(<span class="keywordtype">int</span> code)<span class="keyword"> const </span>{
550
+ <a name="l00525"></a>00525 <span class="keywordflow">return</span> code == EPIPE || code == ECONNREFUSED || code == ECONNRESET
551
+ <a name="l00526"></a>00526 || code == EHOSTUNREACH || code == ENETDOWN || code == ENETUNREACH
552
+ <a name="l00527"></a>00527 || code == ETIMEDOUT;
553
+ <a name="l00528"></a>00528 }
554
+ <a name="l00529"></a>00529
555
+ <a name="l00530"></a>00530 <span class="keyword">public</span>:
556
+ <a name="l00531"></a>00531 AnalyticsLogger() { }
557
+ <a name="l00532"></a>00532
558
+ <a name="l00533"></a>00533 AnalyticsLogger(<span class="keyword">const</span> <span class="keywordtype">string</span> &amp;serverAddress, <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;username,
559
+ <a name="l00534"></a>00534 <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;password, <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;nodeName = <span class="stringliteral">&quot;&quot;</span>)
560
+ <a name="l00535"></a>00535 {
561
+ <a name="l00536"></a>00536 this-&gt;serverAddress = serverAddress;
562
+ <a name="l00537"></a>00537 this-&gt;username = username;
563
+ <a name="l00538"></a>00538 this-&gt;password = password;
564
+ <a name="l00539"></a>00539 <span class="keywordflow">if</span> (nodeName.empty()) {
565
+ <a name="l00540"></a>00540 this-&gt;nodeName = <a class="code" href="namespacePassenger.html#a1d0a66b0e207c46dc6124ff3b2f331e6" title="Returns the system&amp;#39;s host name.">getHostName</a>();
566
+ <a name="l00541"></a>00541 } <span class="keywordflow">else</span> {
567
+ <a name="l00542"></a>00542 this-&gt;nodeName = nodeName;
568
+ <a name="l00543"></a>00543 }
569
+ <a name="l00544"></a>00544 <span class="keywordflow">if</span> (!serverAddress.empty()) {
570
+ <a name="l00545"></a>00545 sharedData.reset(<span class="keyword">new</span> AnalyticsLoggerSharedData());
571
+ <a name="l00546"></a>00546 }
572
+ <a name="l00547"></a>00547 <span class="keywordflow">if</span> (isLocalSocketAddress(serverAddress)) {
573
+ <a name="l00548"></a>00548 maxConnectTries = 10;
574
+ <a name="l00549"></a>00549 } <span class="keywordflow">else</span> {
575
+ <a name="l00550"></a>00550 maxConnectTries = 1;
576
+ <a name="l00551"></a>00551 }
577
+ <a name="l00552"></a>00552 maxConnectTries = 10;
578
+ <a name="l00553"></a>00553 reconnectTimeout = 60 * 1000000;
579
+ <a name="l00554"></a>00554 nextReconnectTime = 0;
580
+ <a name="l00555"></a>00555 }
581
+ <a name="l00556"></a>00556
582
+ <a name="l00557"></a>00557 AnalyticsLogPtr newTransaction(<span class="keyword">const</span> <span class="keywordtype">string</span> &amp;groupName, <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;category = <span class="stringliteral">&quot;requests&quot;</span>,
583
+ <a name="l00558"></a>00558 <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;unionStationKey = <span class="keywordtype">string</span>(),
584
+ <a name="l00559"></a>00559 <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;filters = <span class="keywordtype">string</span>())
585
+ <a name="l00560"></a>00560 {
586
+ <a name="l00561"></a>00561 <span class="keywordflow">if</span> (serverAddress.empty()) {
587
+ <a name="l00562"></a>00562 <span class="keywordflow">return</span> <a class="code" href="group__Support.html#ga41b6c4a82fed72531a147de0505a8396" title="Convenience shortcut for creating a shared_ptr.">ptr</a>(<span class="keyword">new</span> AnalyticsLog());
588
+ <a name="l00563"></a>00563 }
589
+ <a name="l00564"></a>00564
590
+ <a name="l00565"></a>00565 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> <span class="keywordtype">long</span> timestamp = SystemTime::getUsec();
591
+ <a name="l00566"></a>00566 <span class="keywordtype">char</span> txnId[
592
+ <a name="l00567"></a>00567 2 * <span class="keyword">sizeof</span>(<span class="keywordtype">unsigned</span> int) + <span class="comment">// max hex timestamp size</span>
593
+ <a name="l00568"></a>00568 11 + <span class="comment">// space for a random identifier</span>
594
+ <a name="l00569"></a>00569 1 <span class="comment">// null terminator</span>
595
+ <a name="l00570"></a>00570 ];
596
+ <a name="l00571"></a>00571 <span class="keywordtype">char</span> *end;
597
+ <a name="l00572"></a>00572 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> timestampSize;
598
+ <a name="l00573"></a>00573 <span class="keywordtype">char</span> timestampStr[2 * <span class="keyword">sizeof</span>(<span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> long) + 1];
599
+ <a name="l00574"></a>00574
600
+ <a name="l00575"></a>00575 <span class="comment">// &quot;[timestamp]&quot;</span>
601
+ <a name="l00576"></a>00576 <span class="comment">// Our timestamp is like a Unix timestamp but with minutes</span>
602
+ <a name="l00577"></a>00577 <span class="comment">// resolution instead of seconds. 32 bits will last us for</span>
603
+ <a name="l00578"></a>00578 <span class="comment">// about 8000 years.</span>
604
+ <a name="l00579"></a>00579 timestampSize = integerToHexatri&lt;unsigned int&gt;(timestamp / 1000000 / 60,
605
+ <a name="l00580"></a>00580 txnId);
606
+ <a name="l00581"></a>00581 end = txnId + timestampSize;
607
+ <a name="l00582"></a>00582
608
+ <a name="l00583"></a>00583 <span class="comment">// &quot;[timestamp]-&quot;</span>
609
+ <a name="l00584"></a>00584 *end = <span class="charliteral">&#39;-&#39;</span>;
610
+ <a name="l00585"></a>00585 end++;
611
+ <a name="l00586"></a>00586
612
+ <a name="l00587"></a>00587 <span class="comment">// &quot;[timestamp]-[random id]&quot;</span>
613
+ <a name="l00588"></a>00588 randomGenerator.generateAsciiString(end, 11);
614
+ <a name="l00589"></a>00589 end += 11;
615
+ <a name="l00590"></a>00590 *end = <span class="charliteral">&#39;\0&#39;</span>;
616
+ <a name="l00591"></a>00591
617
+ <a name="l00592"></a>00592 integerToHexatri&lt;unsigned long long&gt;(timestamp, timestampStr);
618
+ <a name="l00593"></a>00593
619
+ <a name="l00594"></a>00594 unique_lock&lt;boost::mutex&gt; l(lock);
620
+ <a name="l00595"></a>00595 SharedDataLock sl(sharedData);
621
+ <a name="l00596"></a>00596
622
+ <a name="l00597"></a>00597 <span class="keywordflow">if</span> (SystemTime::getUsec() &gt;= nextReconnectTime) {
623
+ <a name="l00598"></a>00598 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> tryCount = 0;
624
+ <a name="l00599"></a>00599
625
+ <a name="l00600"></a>00600 <span class="keywordflow">while</span> (tryCount &lt; maxConnectTries) {
626
+ <a name="l00601"></a>00601 <span class="keywordflow">try</span> {
627
+ <a name="l00602"></a>00602 <span class="keywordflow">if</span> (!connected()) {
628
+ <a name="l00603"></a>00603 TRACE_POINT();
629
+ <a name="l00604"></a>00604 connect();
630
+ <a name="l00605"></a>00605 }
631
+ <a name="l00606"></a>00606 sharedData-&gt;client.write(<span class="stringliteral">&quot;openTransaction&quot;</span>,
632
+ <a name="l00607"></a>00607 txnId,
633
+ <a name="l00608"></a>00608 groupName.c_str(),
634
+ <a name="l00609"></a>00609 <span class="stringliteral">&quot;&quot;</span>,
635
+ <a name="l00610"></a>00610 category.c_str(),
636
+ <a name="l00611"></a>00611 timestampStr,
637
+ <a name="l00612"></a>00612 unionStationKey.c_str(),
638
+ <a name="l00613"></a>00613 <span class="stringliteral">&quot;true&quot;</span>,
639
+ <a name="l00614"></a>00614 <span class="stringliteral">&quot;true&quot;</span>,
640
+ <a name="l00615"></a>00615 filters.c_str(),
641
+ <a name="l00616"></a>00616 NULL);
642
+ <a name="l00617"></a>00617
643
+ <a name="l00618"></a>00618 vector&lt;string&gt; args;
644
+ <a name="l00619"></a>00619 sharedData-&gt;client.read(args);
645
+ <a name="l00620"></a>00620 <span class="keywordflow">if</span> (args.size() == 2 &amp;&amp; args[0] == <span class="stringliteral">&quot;error&quot;</span>) {
646
+ <a name="l00621"></a>00621 disconnect();
647
+ <a name="l00622"></a>00622 <span class="keywordflow">throw</span> IOException(<span class="stringliteral">&quot;The logging server responded with an error: &quot;</span> + args[1]);
648
+ <a name="l00623"></a>00623 } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (args.empty() || args[0] != <span class="stringliteral">&quot;ok&quot;</span>) {
649
+ <a name="l00624"></a>00624 disconnect();
650
+ <a name="l00625"></a>00625 <span class="keywordflow">throw</span> IOException(<span class="stringliteral">&quot;The logging server sent an unexpected reply.&quot;</span>);
651
+ <a name="l00626"></a>00626 }
652
+ <a name="l00627"></a>00627
653
+ <a name="l00628"></a>00628 <span class="keywordflow">return</span> <a class="code" href="group__Support.html#ga41b6c4a82fed72531a147de0505a8396" title="Convenience shortcut for creating a shared_ptr.">ptr</a>(<span class="keyword">new</span> AnalyticsLog(sharedData,
654
+ <a name="l00629"></a>00629 <span class="keywordtype">string</span>(txnId, end - txnId),
655
+ <a name="l00630"></a>00630 groupName, category,
656
+ <a name="l00631"></a>00631 unionStationKey));
657
+ <a name="l00632"></a>00632 } <span class="keywordflow">catch</span> (<span class="keyword">const</span> SystemException &amp;e) {
658
+ <a name="l00633"></a>00633 TRACE_POINT();
659
+ <a name="l00634"></a>00634 <span class="keywordflow">if</span> (e.code() == ENOENT || isNetworkError(e.code())) {
660
+ <a name="l00635"></a>00635 tryCount++;
661
+ <a name="l00636"></a>00636 disconnect(<span class="keyword">true</span>);
662
+ <a name="l00637"></a>00637 sl.reset(sharedData, <span class="keyword">false</span>);
663
+ <a name="l00638"></a>00638 l.unlock();
664
+ <a name="l00639"></a>00639 <span class="keywordflow">if</span> (tryCount &lt; maxConnectTries) {
665
+ <a name="l00640"></a>00640 syscalls::usleep(RETRY_SLEEP);
666
+ <a name="l00641"></a>00641 }
667
+ <a name="l00642"></a>00642 l.lock();
668
+ <a name="l00643"></a>00643 sl.lock();
669
+ <a name="l00644"></a>00644 } <span class="keywordflow">else</span> {
670
+ <a name="l00645"></a>00645 disconnect();
671
+ <a name="l00646"></a>00646 <span class="keywordflow">throw</span>;
672
+ <a name="l00647"></a>00647 }
673
+ <a name="l00648"></a>00648 }
674
+ <a name="l00649"></a>00649
675
+ <a name="l00650"></a>00650 <span class="comment">// Failed to connect.</span>
676
+ <a name="l00651"></a>00651 P_WARN(<span class="stringliteral">&quot;Cannot connect to the logging agent (&quot;</span> &lt;&lt; serverAddress &lt;&lt; <span class="stringliteral">&quot;); &quot;</span> &lt;&lt;
677
+ <a name="l00652"></a>00652 <span class="stringliteral">&quot;retrying in &quot;</span> &lt;&lt; reconnectTimeout / 1000000 &lt;&lt; <span class="stringliteral">&quot; seconds.&quot;</span>);
678
+ <a name="l00653"></a>00653 nextReconnectTime = SystemTime::getUsec() + reconnectTimeout;
679
+ <a name="l00654"></a>00654 }
680
+ <a name="l00655"></a>00655 }
681
+ <a name="l00656"></a>00656 <span class="keywordflow">return</span> <a class="code" href="group__Support.html#ga41b6c4a82fed72531a147de0505a8396" title="Convenience shortcut for creating a shared_ptr.">ptr</a>(<span class="keyword">new</span> AnalyticsLog());
682
+ <a name="l00657"></a>00657 }
683
+ <a name="l00658"></a>00658
684
+ <a name="l00659"></a>00659 AnalyticsLogPtr continueTransaction(<span class="keyword">const</span> <span class="keywordtype">string</span> &amp;txnId, <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;groupName,
685
+ <a name="l00660"></a>00660 <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;category = <span class="stringliteral">&quot;requests&quot;</span>, <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;unionStationKey = <span class="keywordtype">string</span>())
686
+ <a name="l00661"></a>00661 {
687
+ <a name="l00662"></a>00662 <span class="keywordflow">if</span> (serverAddress.empty() || txnId.empty()) {
688
+ <a name="l00663"></a>00663 <span class="keywordflow">return</span> <a class="code" href="group__Support.html#ga41b6c4a82fed72531a147de0505a8396" title="Convenience shortcut for creating a shared_ptr.">ptr</a>(<span class="keyword">new</span> AnalyticsLog());
689
+ <a name="l00664"></a>00664 }
690
+ <a name="l00665"></a>00665
691
+ <a name="l00666"></a>00666 <span class="keywordtype">char</span> timestampStr[2 * <span class="keyword">sizeof</span>(<span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> long) + 1];
692
+ <a name="l00667"></a>00667 integerToHexatri&lt;unsigned long long&gt;(SystemTime::getUsec(), timestampStr);
693
+ <a name="l00668"></a>00668
694
+ <a name="l00669"></a>00669 unique_lock&lt;boost::mutex&gt; l(lock);
695
+ <a name="l00670"></a>00670 SharedDataLock sl(sharedData);
696
+ <a name="l00671"></a>00671
697
+ <a name="l00672"></a>00672 <span class="keywordflow">if</span> (SystemTime::getUsec() &gt;= nextReconnectTime) {
698
+ <a name="l00673"></a>00673 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> tryCount = 0;
699
+ <a name="l00674"></a>00674
700
+ <a name="l00675"></a>00675 <span class="keywordflow">while</span> (tryCount &lt; maxConnectTries) {
701
+ <a name="l00676"></a>00676 <span class="keywordflow">try</span> {
702
+ <a name="l00677"></a>00677 <span class="keywordflow">if</span> (!connected()) {
703
+ <a name="l00678"></a>00678 TRACE_POINT();
704
+ <a name="l00679"></a>00679 connect();
705
+ <a name="l00680"></a>00680 }
706
+ <a name="l00681"></a>00681 sharedData-&gt;client.write(<span class="stringliteral">&quot;openTransaction&quot;</span>,
707
+ <a name="l00682"></a>00682 txnId.c_str(),
708
+ <a name="l00683"></a>00683 groupName.c_str(),
709
+ <a name="l00684"></a>00684 <span class="stringliteral">&quot;&quot;</span>,
710
+ <a name="l00685"></a>00685 category.c_str(),
711
+ <a name="l00686"></a>00686 timestampStr,
712
+ <a name="l00687"></a>00687 unionStationKey.c_str(),
713
+ <a name="l00688"></a>00688 <span class="stringliteral">&quot;true&quot;</span>,
714
+ <a name="l00689"></a>00689 NULL);
715
+ <a name="l00690"></a>00690 <span class="keywordflow">return</span> <a class="code" href="group__Support.html#ga41b6c4a82fed72531a147de0505a8396" title="Convenience shortcut for creating a shared_ptr.">ptr</a>(<span class="keyword">new</span> AnalyticsLog(sharedData,
716
+ <a name="l00691"></a>00691 txnId, groupName, category,
717
+ <a name="l00692"></a>00692 unionStationKey));
718
+ <a name="l00693"></a>00693 } <span class="keywordflow">catch</span> (<span class="keyword">const</span> SystemException &amp;e) {
719
+ <a name="l00694"></a>00694 TRACE_POINT();
720
+ <a name="l00695"></a>00695 <span class="keywordflow">if</span> (e.code() == EPIPE || isNetworkError(e.code())) {
721
+ <a name="l00696"></a>00696 tryCount++;
722
+ <a name="l00697"></a>00697 disconnect(<span class="keyword">true</span>);
723
+ <a name="l00698"></a>00698 sl.reset(sharedData, <span class="keyword">false</span>);
724
+ <a name="l00699"></a>00699 l.unlock();
725
+ <a name="l00700"></a>00700 <span class="keywordflow">if</span> (tryCount &lt; maxConnectTries) {
726
+ <a name="l00701"></a>00701 syscalls::usleep(RETRY_SLEEP);
727
+ <a name="l00702"></a>00702 }
728
+ <a name="l00703"></a>00703 l.lock();
729
+ <a name="l00704"></a>00704 sl.lock();
730
+ <a name="l00705"></a>00705 } <span class="keywordflow">else</span> {
731
+ <a name="l00706"></a>00706 disconnect();
732
+ <a name="l00707"></a>00707 <span class="keywordflow">throw</span>;
733
+ <a name="l00708"></a>00708 }
734
+ <a name="l00709"></a>00709 }
735
+ <a name="l00710"></a>00710 }
736
+ <a name="l00711"></a>00711
737
+ <a name="l00712"></a>00712 <span class="comment">// Failed to connect.</span>
738
+ <a name="l00713"></a>00713 P_WARN(<span class="stringliteral">&quot;Cannot connect to the logging agent (&quot;</span> &lt;&lt; serverAddress &lt;&lt; <span class="stringliteral">&quot;); &quot;</span> &lt;&lt;
739
+ <a name="l00714"></a>00714 <span class="stringliteral">&quot;retrying in &quot;</span> &lt;&lt; reconnectTimeout / 1000000 &lt;&lt; <span class="stringliteral">&quot; seconds.&quot;</span>);
740
+ <a name="l00715"></a>00715 nextReconnectTime = SystemTime::getUsec() + reconnectTimeout;
741
+ <a name="l00716"></a>00716 }
742
+ <a name="l00717"></a>00717 <span class="keywordflow">return</span> <a class="code" href="group__Support.html#ga41b6c4a82fed72531a147de0505a8396" title="Convenience shortcut for creating a shared_ptr.">ptr</a>(<span class="keyword">new</span> AnalyticsLog());
743
+ <a name="l00718"></a>00718 }
744
+ <a name="l00719"></a>00719
745
+ <a name="l00720"></a>00720 <span class="keywordtype">void</span> setMaxConnectTries(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> value) {
746
+ <a name="l00721"></a>00721 lock_guard&lt;boost::mutex&gt; l(lock);
747
+ <a name="l00722"></a>00722 maxConnectTries = value;
748
+ <a name="l00723"></a>00723 }
749
+ <a name="l00724"></a>00724
750
+ <a name="l00725"></a>00725 <span class="keywordtype">void</span> setReconnectTimeout(<span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> <span class="keywordtype">long</span> usec) {
751
+ <a name="l00726"></a>00726 lock_guard&lt;boost::mutex&gt; l(lock);
752
+ <a name="l00727"></a>00727 reconnectTimeout = usec;
753
+ <a name="l00728"></a>00728 }
754
+ <a name="l00729"></a>00729
755
+ <a name="l00730"></a>00730 <span class="keywordtype">bool</span> isNull()<span class="keyword"> const </span>{
756
+ <a name="l00731"></a>00731 <span class="keywordflow">return</span> serverAddress.empty();
757
+ <a name="l00732"></a>00732 }
758
+ <a name="l00733"></a>00733
759
+ <a name="l00734"></a>00734 <span class="keywordtype">string</span> getAddress()<span class="keyword"> const </span>{
760
+ <a name="l00735"></a>00735 <span class="keywordflow">return</span> serverAddress;
761
+ <a name="l00736"></a>00736 }
762
+ <a name="l00737"></a>00737
763
+ <a name="l00738"></a>00738 <span class="keywordtype">string</span> getUsername()<span class="keyword"> const </span>{
764
+ <a name="l00739"></a>00739 <span class="keywordflow">return</span> username;
765
+ <a name="l00740"></a>00740 }
766
+ <a name="l00741"></a>00741
767
+ <a name="l00742"></a>00742 <span class="keywordtype">string</span> getPassword()<span class="keyword"> const </span>{
768
+ <a name="l00743"></a>00743 <span class="keywordflow">return</span> password;
769
+ <a name="l00744"></a>00744 }
770
+ <a name="l00745"></a>00745
771
+ <a name="l00746"></a>00746 FileDescriptor getConnection()<span class="keyword"> const </span>{
772
+ <a name="l00747"></a>00747 lock_guard&lt;boost::mutex&gt; l(lock);
773
+ <a name="l00748"></a>00748 lock_guard&lt;boost::mutex&gt; l2(sharedData-&gt;lock);
774
+ <a name="l00749"></a>00749 <span class="keywordflow">return</span> sharedData-&gt;client.getConnection();
775
+ <a name="l00750"></a>00750 }
776
+ <a name="l00751"></a>00751 <span class="comment"></span>
777
+ <a name="l00752"></a>00752 <span class="comment"> /**</span>
778
+ <a name="l00753"></a>00753 <span class="comment"> * @post !result.empty()</span>
779
+ <a name="l00754"></a>00754 <span class="comment"> */</span>
780
+ <a name="l00755"></a>00755 <span class="keywordtype">string</span> getNodeName()<span class="keyword"> const </span>{
781
+ <a name="l00756"></a>00756 <span class="keywordflow">return</span> nodeName;
782
+ <a name="l00757"></a>00757 }
783
+ <a name="l00758"></a>00758 };
784
+ <a name="l00759"></a>00759
785
+ <a name="l00760"></a>00760 <span class="keyword">typedef</span> shared_ptr&lt;AnalyticsLogger&gt; AnalyticsLoggerPtr;
786
+ <a name="l00761"></a>00761
787
+ <a name="l00762"></a>00762 } <span class="comment">// namespace Passenger</span>
788
+ <a name="l00763"></a>00763
789
+ <a name="l00764"></a>00764 <span class="preprocessor">#endif </span><span class="comment">/* _PASSENGER_LOGGING_H_ */</span>
790
+ <a name="l00765"></a>00765
721
791
  </pre></div></div>
722
792
  <hr size="1"/><address style="text-align: right;"><small>Generated by&nbsp;
723
793
  <a href="http://www.doxygen.org/index.html">