blob: 1a95c727fdd39af7d0c3e772cb99a7916316f902 [file] [log] [blame]
Yoshiki Iguchia10d37f2020-08-24 12:54:11 +09001// Copyright 2020 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Yoshiki Iguchia10d37f2020-08-24 12:54:11 +09005#include <string>
6#include <vector>
7
8#include <base/command_line.h>
Yoshiki Iguchia10d37f2020-08-24 12:54:11 +09009#include <base/files/file_path.h>
Yoshiki Iguchia10d37f2020-08-24 12:54:11 +090010#include <base/logging.h>
11#include <base/process/process.h>
Yoshiki Iguchia10d37f2020-08-24 12:54:11 +090012#include <base/strings/string_util.h>
13
Yoshiki Iguchic4ac5f92020-12-01 04:17:45 +090014#include <brillo/flag_helper.h>
15
16#include "syslog-cat/syslogcat.h"
17
Yoshiki Iguchia10d37f2020-08-24 12:54:11 +090018namespace {
Yoshiki Iguchic4ac5f92020-12-01 04:17:45 +090019constexpr char kDefaultSeverityStdout[] = "info";
20constexpr char kDefaultSeverityStderr[] = "warn";
Yoshiki Iguchia10d37f2020-08-24 12:54:11 +090021constexpr char kSyslogSocketPath[] = "/run/rsyslogd/stdout";
22
Yoshiki Iguchic4ac5f92020-12-01 04:17:45 +090023int SeverityFromString(const base::StringPiece& severity) {
24 std::string severity_lower = base::ToLowerASCII(severity);
25 if (severity_lower == "0" || severity_lower == "emerg") {
Yoshiki Iguchia10d37f2020-08-24 12:54:11 +090026 return 0;
27 }
28
Yoshiki Iguchic4ac5f92020-12-01 04:17:45 +090029 if (severity_lower == "1" || severity_lower == "alert") {
Yoshiki Iguchia10d37f2020-08-24 12:54:11 +090030 return 1;
31 }
32
Yoshiki Iguchic4ac5f92020-12-01 04:17:45 +090033 if (severity_lower == "2" || severity_lower == "critical" ||
34 severity_lower == "crit") {
Yoshiki Iguchia10d37f2020-08-24 12:54:11 +090035 return 2;
36 }
37
Yoshiki Iguchic4ac5f92020-12-01 04:17:45 +090038 if (severity_lower == "3" || severity_lower == "err" ||
39 severity_lower == "error") {
Yoshiki Iguchia10d37f2020-08-24 12:54:11 +090040 return 3;
41 }
42
Yoshiki Iguchic4ac5f92020-12-01 04:17:45 +090043 if (severity_lower == "4" || severity_lower == "warn" ||
44 severity_lower == "warning") {
Yoshiki Iguchia10d37f2020-08-24 12:54:11 +090045 return 4;
46 }
47
Yoshiki Iguchic4ac5f92020-12-01 04:17:45 +090048 if (severity_lower == "5" || severity_lower == "notice") {
Yoshiki Iguchia10d37f2020-08-24 12:54:11 +090049 return 5;
50 }
51
Yoshiki Iguchic4ac5f92020-12-01 04:17:45 +090052 if (severity_lower == "6" || severity_lower == "info") {
Yoshiki Iguchia10d37f2020-08-24 12:54:11 +090053 return 6;
54 }
55
Yoshiki Iguchic4ac5f92020-12-01 04:17:45 +090056 if (severity_lower == "7" || severity_lower == "debug") {
Yoshiki Iguchia10d37f2020-08-24 12:54:11 +090057 return 7;
58 }
59
60 return -1;
61}
62
Yoshiki Iguchia10d37f2020-08-24 12:54:11 +090063} // namespace
64
65int main(int argc, char* argv[]) {
Yoshiki Iguchic4ac5f92020-12-01 04:17:45 +090066 DEFINE_string(identifier, "", "Identifier string of syslog");
67 DEFINE_string(severity_stdout, kDefaultSeverityStdout,
68 "Severity value which is used in sendin stdout to syslog");
69 DEFINE_string(severity_stderr, kDefaultSeverityStderr,
70 "Severity value which is used in sendin stderr to syslog");
Yoshiki Iguchia10d37f2020-08-24 12:54:11 +090071
Yoshiki Iguchic4ac5f92020-12-01 04:17:45 +090072 brillo::FlagHelper::Init(
73 argc, argv,
74 "Captures the stdout/stderr of the specified program and forward them "
75 "to syslog.");
Yoshiki Iguchia10d37f2020-08-24 12:54:11 +090076
Yoshiki Iguchic4ac5f92020-12-01 04:17:45 +090077 const auto& sv = base::CommandLine::ForCurrentProcess()->GetArgs();
78 if (sv.size() == 0) {
79 LOG(ERROR) << "Syslog-cat requres the command line to execute.";
Yoshiki Iguchia10d37f2020-08-24 12:54:11 +090080 return 1;
81 }
82
Yoshiki Iguchic4ac5f92020-12-01 04:17:45 +090083 const std::string& target_command = sv[0];
84
Yoshiki Iguchia10d37f2020-08-24 12:54:11 +090085 // Prepare a identifier.
Yoshiki Iguchic4ac5f92020-12-01 04:17:45 +090086 std::string identifier = FLAGS_identifier;
87 if (identifier.empty()) {
88 // Fallback to the default.
89 identifier = base::FilePath(target_command).BaseName().value();
Yoshiki Iguchia10d37f2020-08-24 12:54:11 +090090 }
91 if (identifier.empty()) {
Yoshiki Iguchic4ac5f92020-12-01 04:17:45 +090092 // Failed to fallback for some reason.
Yoshiki Iguchia10d37f2020-08-24 12:54:11 +090093 LOG(ERROR) << "Failed to extract a identifier string.";
94 return 1;
95 }
96
97 // Prepare a severity for stdout.
Yoshiki Iguchic4ac5f92020-12-01 04:17:45 +090098 int severity_stdout = SeverityFromString(FLAGS_severity_stdout);
Yoshiki Iguchia10d37f2020-08-24 12:54:11 +090099 if (severity_stdout < 0) {
Yoshiki Iguchic4ac5f92020-12-01 04:17:45 +0900100 LOG(ERROR) << "Invalid --severity_stdout value '" << severity_stdout
101 << "'. It must be a number between 0 (EMERG) and 7 (DEBUG) or "
102 "valid severity string.";
Yoshiki Iguchia10d37f2020-08-24 12:54:11 +0900103 return 1;
104 }
105
106 // Prepare a severity for stderr.
Yoshiki Iguchic4ac5f92020-12-01 04:17:45 +0900107 int severity_stderr = SeverityFromString(FLAGS_severity_stderr);
Yoshiki Iguchia10d37f2020-08-24 12:54:11 +0900108 if (severity_stderr < 0) {
Yoshiki Iguchic4ac5f92020-12-01 04:17:45 +0900109 LOG(ERROR) << "Invalid --severity_stderr value '" << severity_stderr
110 << "'. It must be a number between 0 (EMERG) and 7 (DEBUG) or "
111 "valid severity string.";
Yoshiki Iguchia10d37f2020-08-24 12:54:11 +0900112 return 1;
113 }
114
Yoshiki Iguchia10d37f2020-08-24 12:54:11 +0900115 // Prepare a command line for the target process.
116 int target_command_argc = sv.size();
117 std::vector<const char*> target_command_argv(target_command_argc + 1);
118 for (int i = 0; i < target_command_argc; i++)
119 target_command_argv[i] = sv[i].c_str();
120 target_command_argv[target_command_argc] = nullptr;
121
Yoshiki Iguchic4ac5f92020-12-01 04:17:45 +0900122 ExecuteCommandWithRedirection(target_command, target_command_argv, identifier,
123 severity_stdout, severity_stderr,
124 base::FilePath(kSyslogSocketPath),
125 base::FilePath(kSyslogSocketPath));
Yoshiki Iguchia10d37f2020-08-24 12:54:11 +0900126
Yoshiki Iguchic4ac5f92020-12-01 04:17:45 +0900127 // The method above should never return unless an error happens.
Yoshiki Iguchia10d37f2020-08-24 12:54:11 +0900128
Yoshiki Iguchic4ac5f92020-12-01 04:17:45 +0900129 // Crashes itself by the FATAL error message.
130 LOG(FATAL) << "Executing the command is unexpectedly failed.";
Yoshiki Iguchia10d37f2020-08-24 12:54:11 +0900131}