passenger 4.0.42 → 4.0.43
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of passenger might be problematic. Click here for more details.
- checksums.yaml +8 -8
- checksums.yaml.gz.asc +7 -7
- data.tar.gz.asc +7 -7
- data/CHANGELOG +13 -0
- data/CONTRIBUTING.md +2 -19
- data/build/agents.rb +4 -1
- data/build/cxx_tests.rb +7 -2
- data/build/debian.rb +1 -1
- data/debian.template/control.template +0 -2
- data/doc/CodingTipsAndPitfalls.md +56 -0
- data/doc/Users guide Apache.idmap.txt +16 -14
- data/doc/Users guide Nginx.idmap.txt +8 -6
- data/doc/Users guide Standalone.idmap.txt +3 -1
- data/doc/Users guide Standalone.txt +1 -1
- data/doc/users_guide_snippets/environment_variables.txt +1 -0
- data/doc/users_guide_snippets/installation.txt +5 -5
- data/doc/users_guide_snippets/support_information.txt +42 -9
- data/doc/users_guide_snippets/troubleshooting/default.txt +42 -0
- data/ext/common/ApplicationPool2/Common.h +1 -0
- data/ext/common/ApplicationPool2/DirectSpawner.h +2 -7
- data/ext/common/ApplicationPool2/DummySpawner.h +1 -1
- data/ext/common/ApplicationPool2/Group.h +4 -2
- data/ext/common/ApplicationPool2/Options.h +9 -7
- data/ext/common/ApplicationPool2/Pool.h +83 -40
- data/ext/common/ApplicationPool2/Process.h +2 -6
- data/ext/common/ApplicationPool2/README.md +0 -40
- data/ext/common/ApplicationPool2/SmartSpawner.h +2 -9
- data/ext/common/ApplicationPool2/Spawner.h +1 -4
- data/ext/common/ApplicationPool2/SpawnerFactory.h +6 -9
- data/ext/common/ApplicationPool2/SuperGroup.h +3 -3
- data/ext/common/Constants.h +1 -1
- data/ext/common/UnionStation/Connection.h +227 -0
- data/ext/common/UnionStation/Core.h +497 -0
- data/ext/common/UnionStation/ScopeLog.h +172 -0
- data/ext/common/UnionStation/Transaction.h +276 -0
- data/ext/common/Utils.cpp +83 -8
- data/ext/common/Utils.h +25 -4
- data/ext/common/Utils/AnsiColorConstants.h +1 -0
- data/ext/common/Utils/ProcessMetricsCollector.h +6 -170
- data/ext/common/Utils/SpeedMeter.h +258 -0
- data/ext/common/Utils/StrIntUtils.cpp +6 -0
- data/ext/common/Utils/StringScanning.h +277 -0
- data/ext/common/Utils/SystemMetricsCollector.h +1460 -0
- data/ext/common/agents/Base.cpp +8 -8
- data/ext/common/agents/HelperAgent/Main.cpp +12 -6
- data/ext/common/agents/HelperAgent/RequestHandler.h +15 -16
- data/ext/common/agents/HelperAgent/SystemMetricsTool.cpp +199 -0
- data/ext/common/agents/LoggingAgent/LoggingServer.h +2 -1
- data/ext/common/agents/SpawnPreparer.cpp +20 -32
- data/lib/phusion_passenger.rb +1 -1
- data/lib/phusion_passenger/config/list_instances_command.rb +118 -0
- data/lib/phusion_passenger/config/main.rb +22 -4
- data/lib/phusion_passenger/config/system_metrics_command.rb +37 -0
- data/lib/phusion_passenger/config/utils.rb +1 -1
- data/lib/phusion_passenger/loader_shared_helpers.rb +8 -5
- data/lib/phusion_passenger/platform_info/compiler.rb +1 -1
- data/resources/templates/error_layout.html.template +3 -3
- data/test/cxx/ApplicationPool2/DirectSpawnerTest.cpp +3 -5
- data/test/cxx/ApplicationPool2/PoolTest.cpp +1 -3
- data/test/cxx/ApplicationPool2/ProcessTest.cpp +4 -4
- data/test/cxx/ApplicationPool2/SmartSpawnerTest.cpp +5 -7
- data/test/cxx/RequestHandlerTest.cpp +9 -3
- data/test/cxx/UnionStationTest.cpp +61 -64
- metadata +13 -4
- metadata.gz.asc +7 -7
- data/ext/common/UnionStation.h +0 -968
- data/helper-scripts/system-memory-stats.py +0 -207
data/ext/common/agents/Base.cpp
CHANGED
@@ -438,7 +438,7 @@ dumpFileDescriptorInfoWithLsof(AbortHandlerState &state, void *userData) {
|
|
438
438
|
end = appendULL(end, state.pid);
|
439
439
|
*end = '\0';
|
440
440
|
|
441
|
-
closeAllFileDescriptors(2);
|
441
|
+
closeAllFileDescriptors(2, true);
|
442
442
|
|
443
443
|
execlp("lsof", "lsof", "-p", state.messageBuf, "-nP", (const char * const) 0);
|
444
444
|
|
@@ -457,7 +457,7 @@ dumpFileDescriptorInfoWithLs(AbortHandlerState &state, char *end) {
|
|
457
457
|
|
458
458
|
pid = asyncFork();
|
459
459
|
if (pid == 0) {
|
460
|
-
closeAllFileDescriptors(2);
|
460
|
+
closeAllFileDescriptors(2, true);
|
461
461
|
// The '-v' is for natural sorting on Linux. On BSD -v means something else but it's harmless.
|
462
462
|
execlp("ls", "ls", "-lv", state.messageBuf, (const char * const) 0);
|
463
463
|
_exit(1);
|
@@ -517,7 +517,7 @@ dumpWithCrashWatch(AbortHandlerState &state) {
|
|
517
517
|
|
518
518
|
pid_t child = asyncFork();
|
519
519
|
if (child == 0) {
|
520
|
-
closeAllFileDescriptors(2);
|
520
|
+
closeAllFileDescriptors(2, true);
|
521
521
|
execlp("crash-watch", "crash-watch", "--dump", pidStr, (char * const) 0);
|
522
522
|
if (errno == ENOENT) {
|
523
523
|
safePrintErr("Crash-watch is not installed. Please install it with 'gem install crash-watch' "
|
@@ -583,7 +583,7 @@ dumpWithCrashWatch(AbortHandlerState &state) {
|
|
583
583
|
|
584
584
|
close(p[1]);
|
585
585
|
dup2(p[0], STDIN_FILENO);
|
586
|
-
closeAllFileDescriptors(2);
|
586
|
+
closeAllFileDescriptors(2, true);
|
587
587
|
|
588
588
|
char *command = end;
|
589
589
|
end = appendText(end, "exec ");
|
@@ -664,7 +664,7 @@ dumpDiagnostics(AbortHandlerState &state) {
|
|
664
664
|
// Dump human-readable time string and string.
|
665
665
|
pid = asyncFork();
|
666
666
|
if (pid == 0) {
|
667
|
-
closeAllFileDescriptors(2);
|
667
|
+
closeAllFileDescriptors(2, true);
|
668
668
|
execlp("date", "date", (const char * const) 0);
|
669
669
|
_exit(1);
|
670
670
|
} else if (pid == -1) {
|
@@ -676,7 +676,7 @@ dumpDiagnostics(AbortHandlerState &state) {
|
|
676
676
|
// Dump system uname.
|
677
677
|
pid = asyncFork();
|
678
678
|
if (pid == 0) {
|
679
|
-
closeAllFileDescriptors(2);
|
679
|
+
closeAllFileDescriptors(2, true);
|
680
680
|
execlp("uname", "uname", "-mprsv", (const char * const) 0);
|
681
681
|
_exit(1);
|
682
682
|
} else if (pid == -1) {
|
@@ -688,7 +688,7 @@ dumpDiagnostics(AbortHandlerState &state) {
|
|
688
688
|
// Dump ulimit.
|
689
689
|
pid = asyncFork();
|
690
690
|
if (pid == 0) {
|
691
|
-
closeAllFileDescriptors(2);
|
691
|
+
closeAllFileDescriptors(2, true);
|
692
692
|
execlp("ulimit", "ulimit", "-a", (const char * const) 0);
|
693
693
|
// On Linux 'ulimit' is a shell builtin, not a command.
|
694
694
|
execlp("/bin/sh", "/bin/sh", "-c", "ulimit -a", (const char * const) 0);
|
@@ -929,7 +929,7 @@ abortHandler(int signo, siginfo_t *info, void *ctx) {
|
|
929
929
|
|
930
930
|
child = asyncFork();
|
931
931
|
if (child == 0) {
|
932
|
-
closeAllFileDescriptors(2);
|
932
|
+
closeAllFileDescriptors(2, true);
|
933
933
|
#ifdef __APPLE__
|
934
934
|
execlp("osascript", "osascript", "-e", "beep 2", (const char * const) 0);
|
935
935
|
safePrintErr("Cannot execute 'osascript' command\n");
|
@@ -53,6 +53,7 @@
|
|
53
53
|
#include <agents/HelperAgent/RequestHandler.h>
|
54
54
|
#include <agents/HelperAgent/RequestHandler.cpp>
|
55
55
|
#include <agents/HelperAgent/AgentOptions.h>
|
56
|
+
#include <agents/HelperAgent/SystemMetricsTool.cpp>
|
56
57
|
|
57
58
|
#include <agents/Base.h>
|
58
59
|
#include <Constants.h>
|
@@ -63,7 +64,7 @@
|
|
63
64
|
#include <ResourceLocator.h>
|
64
65
|
#include <BackgroundEventLoop.cpp>
|
65
66
|
#include <ServerInstanceDir.h>
|
66
|
-
#include <UnionStation.h>
|
67
|
+
#include <UnionStation/Core.h>
|
67
68
|
#include <Exceptions.h>
|
68
69
|
#include <MultiLibeio.cpp>
|
69
70
|
#include <Utils.h>
|
@@ -261,7 +262,7 @@ private:
|
|
261
262
|
FileDescriptor requestSocket;
|
262
263
|
ServerInstanceDir serverInstanceDir;
|
263
264
|
ServerInstanceDir::GenerationPtr generation;
|
264
|
-
UnionStation::
|
265
|
+
UnionStation::CorePtr unionStationCore;
|
265
266
|
RandomGeneratorPtr randomGenerator;
|
266
267
|
SpawnerFactoryPtr spawnerFactory;
|
267
268
|
PoolPtr pool;
|
@@ -459,11 +460,11 @@ public:
|
|
459
460
|
}
|
460
461
|
|
461
462
|
UPDATE_TRACE_POINT();
|
462
|
-
|
463
|
+
unionStationCore = boost::make_shared<UnionStation::Core>(options.loggingAgentAddress,
|
463
464
|
"logging", options.loggingAgentPassword);
|
464
|
-
spawnerFactory = boost::make_shared<SpawnerFactory>(
|
465
|
-
|
466
|
-
pool = boost::make_shared<Pool>(spawnerFactory,
|
465
|
+
spawnerFactory = boost::make_shared<SpawnerFactory>(resourceLocator,
|
466
|
+
generation, boost::make_shared<SpawnerConfig>(randomGenerator));
|
467
|
+
pool = boost::make_shared<Pool>(spawnerFactory, unionStationCore,
|
467
468
|
randomGenerator, &options);
|
468
469
|
pool->initialize();
|
469
470
|
pool->setMax(options.maxPoolSize);
|
@@ -620,6 +621,11 @@ public:
|
|
620
621
|
int
|
621
622
|
main(int argc, char *argv[]) {
|
622
623
|
TRACE_POINT();
|
624
|
+
|
625
|
+
if (argc > 1 && strcmp(argv[1], "system-metrics") == 0) {
|
626
|
+
return SystemMetricsTool::main(argc, argv);
|
627
|
+
}
|
628
|
+
|
623
629
|
AgentOptionsPtr options;
|
624
630
|
try {
|
625
631
|
options = boost::make_shared<AgentOptions>(
|
@@ -133,7 +133,9 @@
|
|
133
133
|
#include <EventedBufferedInput.h>
|
134
134
|
#include <MessageReadersWriters.h>
|
135
135
|
#include <Constants.h>
|
136
|
-
#include <UnionStation.h>
|
136
|
+
#include <UnionStation/Core.h>
|
137
|
+
#include <UnionStation/Transaction.h>
|
138
|
+
#include <UnionStation/ScopeLog.h>
|
137
139
|
#include <ApplicationPool2/Pool.h>
|
138
140
|
#include <Utils/StrIntUtils.h>
|
139
141
|
#include <Utils/IOUtils.h>
|
@@ -528,16 +530,16 @@ public:
|
|
528
530
|
}
|
529
531
|
|
530
532
|
bool useUnionStation() const {
|
531
|
-
return options.
|
533
|
+
return options.transaction != NULL;
|
532
534
|
}
|
533
535
|
|
534
|
-
UnionStation::
|
535
|
-
return options.
|
536
|
+
UnionStation::TransactionPtr getUnionStationTransaction() const {
|
537
|
+
return options.transaction;
|
536
538
|
}
|
537
539
|
|
538
540
|
void beginScopeLog(UnionStation::ScopeLog **scopeLog, const char *name) {
|
539
|
-
if (options.
|
540
|
-
*scopeLog = new UnionStation::ScopeLog(options.
|
541
|
+
if (options.transaction != NULL) {
|
542
|
+
*scopeLog = new UnionStation::ScopeLog(options.transaction, name);
|
541
543
|
}
|
542
544
|
}
|
543
545
|
|
@@ -550,7 +552,7 @@ public:
|
|
550
552
|
}
|
551
553
|
|
552
554
|
void logMessage(const StaticString &message) {
|
553
|
-
options.
|
555
|
+
options.transaction->message(message);
|
554
556
|
}
|
555
557
|
|
556
558
|
void verifyInvariants() const {
|
@@ -617,16 +619,13 @@ public:
|
|
617
619
|
|
618
620
|
private:
|
619
621
|
friend class Client;
|
620
|
-
typedef UnionStation::LoggerFactory LoggerFactory;
|
621
|
-
typedef UnionStation::LoggerFactoryPtr LoggerFactoryPtr;
|
622
|
-
typedef UnionStation::LoggerPtr LoggerPtr;
|
623
622
|
|
624
623
|
const SafeLibevPtr libev;
|
625
624
|
FileDescriptor requestSocket;
|
626
625
|
PoolPtr pool;
|
627
626
|
const AgentOptions &options;
|
628
627
|
const ResourceLocator resourceLocator;
|
629
|
-
|
628
|
+
UnionStation::CorePtr unionStationCore;
|
630
629
|
ev::io requestSocketWatcher;
|
631
630
|
ev::timer resumeSocketWatcherTimer;
|
632
631
|
HashMap<int, ClientPtr> clients;
|
@@ -1933,9 +1932,9 @@ private:
|
|
1933
1932
|
return;
|
1934
1933
|
}
|
1935
1934
|
|
1936
|
-
client->options.
|
1935
|
+
client->options.transaction = unionStationCore->newTransaction(
|
1937
1936
|
options.getAppGroupName(), "requests", key, filters);
|
1938
|
-
if (!client->options.
|
1937
|
+
if (!client->options.transaction->isNull()) {
|
1939
1938
|
client->options.analytics = true;
|
1940
1939
|
client->options.unionStationKey = key;
|
1941
1940
|
}
|
@@ -2327,7 +2326,7 @@ private:
|
|
2327
2326
|
|
2328
2327
|
if (client->options.analytics) {
|
2329
2328
|
data.push_back(makeStaticStringWithNull("PASSENGER_TXN_ID"));
|
2330
|
-
data.push_back(makeStaticStringWithNull(client->options.
|
2329
|
+
data.push_back(makeStaticStringWithNull(client->options.transaction->getTxnId()));
|
2331
2330
|
}
|
2332
2331
|
|
2333
2332
|
uint32_t dataSize = 0;
|
@@ -2402,7 +2401,7 @@ private:
|
|
2402
2401
|
|
2403
2402
|
if (client->options.analytics) {
|
2404
2403
|
data.append("Passenger-Txn-Id: ");
|
2405
|
-
data.append(client->options.
|
2404
|
+
data.append(client->options.transaction->getTxnId());
|
2406
2405
|
data.append("\r\n");
|
2407
2406
|
}
|
2408
2407
|
|
@@ -2614,7 +2613,7 @@ public:
|
|
2614
2613
|
{
|
2615
2614
|
accept4Available = true;
|
2616
2615
|
connectPasswordTimeout = 15000;
|
2617
|
-
|
2616
|
+
unionStationCore = pool->unionStationCore;
|
2618
2617
|
|
2619
2618
|
requestSocketWatcher.set(_requestSocket, ev::READ);
|
2620
2619
|
requestSocketWatcher.set(_libev->getLoop());
|
@@ -0,0 +1,199 @@
|
|
1
|
+
/*
|
2
|
+
* Phusion Passenger - https://www.phusionpassenger.com/
|
3
|
+
* Copyright (c) 2014 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
|
+
#include <iostream>
|
26
|
+
#include <string>
|
27
|
+
#include <unistd.h>
|
28
|
+
#include <cstdio>
|
29
|
+
#include <cstring>
|
30
|
+
#include <Utils.h>
|
31
|
+
#include <Utils/StrIntUtils.h>
|
32
|
+
#include <Utils/SystemMetricsCollector.h>
|
33
|
+
|
34
|
+
namespace SystemMetricsTool {
|
35
|
+
|
36
|
+
using namespace std;
|
37
|
+
using namespace Passenger;
|
38
|
+
|
39
|
+
struct Options {
|
40
|
+
bool xml;
|
41
|
+
SystemMetrics::XmlOptions xmlOptions;
|
42
|
+
SystemMetrics::DescriptionOptions descOptions;
|
43
|
+
int interval;
|
44
|
+
bool stdin;
|
45
|
+
bool exitOnUnexpectedError;
|
46
|
+
bool help;
|
47
|
+
|
48
|
+
Options() {
|
49
|
+
xml = false;
|
50
|
+
descOptions.colors = isatty(1);
|
51
|
+
interval = -1;
|
52
|
+
stdin = false;
|
53
|
+
exitOnUnexpectedError = true;
|
54
|
+
help = false;
|
55
|
+
}
|
56
|
+
};
|
57
|
+
|
58
|
+
static bool
|
59
|
+
isFlag(const char *arg, char shortFlagName, const char *longFlagName) {
|
60
|
+
return strcmp(arg, longFlagName) == 0
|
61
|
+
|| (shortFlagName != '\0' && arg[0] == '-'
|
62
|
+
&& arg[1] == shortFlagName && arg[2] == '\0');
|
63
|
+
}
|
64
|
+
|
65
|
+
static void
|
66
|
+
usage() {
|
67
|
+
printf("Usage: passenger-config system-metrics [OPTIONS]\n");
|
68
|
+
printf("Displays various metrics about the system.\n");
|
69
|
+
printf("\n");
|
70
|
+
printf("Options:\n");
|
71
|
+
printf(" --xml Output in XML format\n");
|
72
|
+
printf(" --no-general Do not display general metrics\n");
|
73
|
+
printf(" --no-cpu Do not display CPU metrics\n");
|
74
|
+
printf(" --no-memory Do not display memory metrics\n");
|
75
|
+
printf(" --force-colors Display colors even if stdout is not a TTY\n");
|
76
|
+
printf(" -w --watch INTERVAL Reprint metrics every INTERVAL seconds\n");
|
77
|
+
printf(" --stdin Reprint metrics every time a newline is received on\n");
|
78
|
+
printf(" stdin, until EOF. Mutually exclusive with --watch\n");
|
79
|
+
printf(" --no-exit-on-unexpected-error Normally, if an unexpected error is\n");
|
80
|
+
printf(" encountered while collecting system metrics, this\n");
|
81
|
+
printf(" program will exit with an error code. This option\n");
|
82
|
+
printf(" suppresses that\n");
|
83
|
+
printf(" -h, --help Show this help\n");
|
84
|
+
}
|
85
|
+
|
86
|
+
static Options
|
87
|
+
parseOptions(int argc, char *argv[]) {
|
88
|
+
Options options;
|
89
|
+
int i = 2;
|
90
|
+
|
91
|
+
while (i < argc) {
|
92
|
+
if (isFlag(argv[i], '\0', "--xml")) {
|
93
|
+
options.xml = true;
|
94
|
+
i++;
|
95
|
+
} else if (isFlag(argv[i], '\0', "--no-general")) {
|
96
|
+
options.xmlOptions.general = false;
|
97
|
+
options.descOptions.general = false;
|
98
|
+
i++;
|
99
|
+
} else if (isFlag(argv[i], '\0', "--no-cpu")) {
|
100
|
+
options.xmlOptions.cpu = false;
|
101
|
+
options.descOptions.cpu = false;
|
102
|
+
i++;
|
103
|
+
} else if (isFlag(argv[i], '\0', "--no-memory")) {
|
104
|
+
options.xmlOptions.memory = false;
|
105
|
+
options.descOptions.memory = false;
|
106
|
+
i++;
|
107
|
+
} else if (isFlag(argv[i], '\0', "--force-colors")) {
|
108
|
+
options.descOptions.colors = true;
|
109
|
+
i++;
|
110
|
+
} else if (isFlag(argv[i], 'w', "--watch")) {
|
111
|
+
if (argc >= i + 2) {
|
112
|
+
options.interval = atoi(argv[i + 1]);
|
113
|
+
i += 2;
|
114
|
+
} else {
|
115
|
+
fprintf(stderr, "ERROR: extra argument required for --watch\n");
|
116
|
+
usage();
|
117
|
+
exit(1);
|
118
|
+
}
|
119
|
+
} else if (isFlag(argv[i], '\0', "--stdin")) {
|
120
|
+
options.stdin = true;
|
121
|
+
i++;
|
122
|
+
} else if (isFlag(argv[i], '\0', "--no-exit-on-unexpected-error")) {
|
123
|
+
options.exitOnUnexpectedError = false;
|
124
|
+
i++;
|
125
|
+
} else if (isFlag(argv[i], 'h', "--help")) {
|
126
|
+
options.help = true;
|
127
|
+
i++;
|
128
|
+
} else {
|
129
|
+
fprintf(stderr, "ERROR: unrecognized argument %s\n", argv[i]);
|
130
|
+
usage();
|
131
|
+
exit(1);
|
132
|
+
}
|
133
|
+
}
|
134
|
+
if (options.interval != -1 && options.stdin) {
|
135
|
+
fprintf(stderr, "ERROR: --watch and --stdin are mutually exclusive.\n");
|
136
|
+
exit(1);
|
137
|
+
}
|
138
|
+
return options;
|
139
|
+
}
|
140
|
+
|
141
|
+
static bool
|
142
|
+
waitForNextLine() {
|
143
|
+
char buf[1024];
|
144
|
+
return fgets(buf, sizeof(buf), stdin) != NULL;
|
145
|
+
}
|
146
|
+
|
147
|
+
static void
|
148
|
+
perform(const Options &options, SystemMetricsCollector &collector, SystemMetrics &metrics) {
|
149
|
+
try {
|
150
|
+
collector.collect(metrics);
|
151
|
+
if (options.xml) {
|
152
|
+
cout << "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
|
153
|
+
metrics.toXml(cout, options.xmlOptions);
|
154
|
+
cout << endl;
|
155
|
+
} else {
|
156
|
+
metrics.toDescription(cout, options.descOptions);
|
157
|
+
}
|
158
|
+
} catch (const RuntimeException &e) {
|
159
|
+
fprintf(stderr, "An error occurred while collecting system metrics: %s\n", e.what());
|
160
|
+
if (options.exitOnUnexpectedError) {
|
161
|
+
exit(1);
|
162
|
+
}
|
163
|
+
}
|
164
|
+
}
|
165
|
+
|
166
|
+
static int
|
167
|
+
main(int argc, char *argv[]) {
|
168
|
+
Options options = parseOptions(argc, argv);
|
169
|
+
if (options.help) {
|
170
|
+
usage();
|
171
|
+
return 0;
|
172
|
+
}
|
173
|
+
|
174
|
+
SystemMetricsCollector collector;
|
175
|
+
SystemMetrics metrics;
|
176
|
+
|
177
|
+
if (options.descOptions.cpu) {
|
178
|
+
collector.collect(metrics);
|
179
|
+
// We have to measure system metrics within an interval
|
180
|
+
// in order to determine the CPU usage.
|
181
|
+
usleep(50000);
|
182
|
+
}
|
183
|
+
|
184
|
+
if (options.stdin) {
|
185
|
+
while (waitForNextLine()) {
|
186
|
+
perform(options, collector, metrics);
|
187
|
+
}
|
188
|
+
} else {
|
189
|
+
do {
|
190
|
+
perform(options, collector, metrics);
|
191
|
+
if (options.interval != -1) {
|
192
|
+
sleep(options.interval);
|
193
|
+
}
|
194
|
+
} while (options.interval != -1);
|
195
|
+
}
|
196
|
+
return 0;
|
197
|
+
}
|
198
|
+
|
199
|
+
} // namespace SystemMetricsTool
|
@@ -534,7 +534,8 @@ private:
|
|
534
534
|
}
|
535
535
|
|
536
536
|
bool supportedCategory(const StaticString &category) const {
|
537
|
-
return category == "requests" || category == "processes"
|
537
|
+
return category == "requests" || category == "processes"
|
538
|
+
|| category == "exceptions" || category == "system_metrics";
|
538
539
|
}
|
539
540
|
|
540
541
|
LogSinkPtr openLogFile() {
|
@@ -41,6 +41,8 @@
|
|
41
41
|
#include <unistd.h>
|
42
42
|
#include <stdlib.h>
|
43
43
|
#include <string>
|
44
|
+
#include <sstream>
|
45
|
+
#include <Utils/SystemMetricsCollector.h>
|
44
46
|
#include <Utils/Base64.h>
|
45
47
|
|
46
48
|
using namespace std;
|
@@ -148,42 +150,28 @@ dumpInformation() {
|
|
148
150
|
fclose(f);
|
149
151
|
}
|
150
152
|
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
strerror(e), e);
|
162
|
-
} else {
|
163
|
-
waitpid(pid, NULL, 0);
|
164
|
-
}
|
165
|
-
fclose(f);
|
153
|
+
SystemMetrics metrics;
|
154
|
+
bool collected = false;
|
155
|
+
try {
|
156
|
+
SystemMetricsCollector collector;
|
157
|
+
collector.collect(metrics);
|
158
|
+
usleep(50000); // Correct collect CPU metrics.
|
159
|
+
collector.collect(metrics);
|
160
|
+
collected = true;
|
161
|
+
} catch (const RuntimeException &e) {
|
162
|
+
fprintf(stderr, "Warning: %s\n", e.what());
|
166
163
|
}
|
167
|
-
|
168
|
-
|
169
|
-
// TODO: call helper-scripts/system-memory-stats.py
|
170
|
-
f = fopen((dir + "/sysmemory").c_str(), "w");
|
164
|
+
if (collected) {
|
165
|
+
f = fopen((dir + "/system_metrics").c_str(), "w");
|
171
166
|
if (f != NULL) {
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
} else if (pid == -1) {
|
178
|
-
int e = errno;
|
179
|
-
fprintf(stderr, "Error: cannot fork a new process: %s (errno=%d)\n",
|
180
|
-
strerror(e), e);
|
181
|
-
} else {
|
182
|
-
waitpid(pid, NULL, 0);
|
183
|
-
}
|
167
|
+
stringstream stream;
|
168
|
+
metrics.toDescription(stream);
|
169
|
+
string info = stream.str();
|
170
|
+
|
171
|
+
fwrite(info.data(), 1, info.size(), f);
|
184
172
|
fclose(f);
|
185
173
|
}
|
186
|
-
|
174
|
+
}
|
187
175
|
}
|
188
176
|
|
189
177
|
// Usage: SpawnPreparer <working directory> <envvars> <executable> <exec args...>
|