2 * Copyright (c) 2014-present, Facebook, Inc.
5 * This source code is licensed in accordance with the terms specified in
6 * the LICENSE file found in the root directory of this source tree.
9 #include "filesystem_logger.h"
13 #include <osquery/flags.h>
14 #include <osquery/logger.h>
15 #include <osquery/utils/config/default_paths.h>
17 namespace fs = boost::filesystem;
20 * This is the mode that Glog uses for logfiles.
21 * Must be at the top level (i.e. outside of the `osquery` namespace).
23 DECLARE_int32(logfile_mode);
30 "Directory path for ERROR/WARN/INFO and results logging");
31 /// Legacy, backward compatible "osquery_log_dir" CLI option.
32 FLAG_ALIAS(std::string, osquery_log_dir, logger_path);
34 FLAG(int32, logger_mode, 0640, "Decimal mode for log files (default '0640')");
36 const std::string kFilesystemLoggerFilename = "osqueryd.results.log";
37 const std::string kFilesystemLoggerSnapshots = "osqueryd.snapshots.log";
39 Status FilesystemLoggerPlugin::setUp() {
40 log_path_ = fs::path(FLAGS_logger_path);
42 // Ensure that the Glog status logs use the same mode as our results log.
43 // Glog 0.3.4 does not support a logfile mode.
44 // FLAGS_logfile_mode = FLAGS_logger_mode;
46 // Ensure that we create the results log here.
47 return logStringToFile("", kFilesystemLoggerFilename, true);
50 Status FilesystemLoggerPlugin::logString(const std::string& s) {
51 return logStringToFile(s, kFilesystemLoggerFilename);
54 Status FilesystemLoggerPlugin::logStringToFile(const std::string& s,
55 const std::string& filename,
57 WriteLock lock(mutex_);
60 status = writeTextFile((log_path_ / filename).string(),
61 (empty) ? "" : s + '\n',
63 } catch (const std::exception& e) {
64 return Status(1, e.what());
69 Status FilesystemLoggerPlugin::logStatus(
70 const std::vector<StatusLogLine>& log) {
71 for (const auto& item : log) {
72 // Emit this intermediate log to the Glog filesystem logger.
73 google::LogMessage(item.filename.c_str(),
74 static_cast<int>(item.line),
75 (google::LogSeverity)item.severity)
80 return Status(0, "OK");
83 Status FilesystemLoggerPlugin::logSnapshot(const std::string& s) {
84 // Send the snapshot data to a separate filename.
85 return logStringToFile(s, kFilesystemLoggerSnapshots);
88 void FilesystemLoggerPlugin::init(const std::string& name,
89 const std::vector<StatusLogLine>& log) {
90 // Stop the internal Glog facilities.
91 google::ShutdownGoogleLogging();
93 // The log dir is used for status logging and the filesystem results logs.
94 if (isWritable(log_path_.string()).ok()) {
95 FLAGS_log_dir = log_path_.string();
96 FLAGS_logtostderr = false;
98 // If we cannot write logs to the filesystem, fallback to stderr.
99 // The caller (flags/options) might 'also' be logging to stderr using
100 // debug, verbose, etc.
101 FLAGS_logtostderr = true;
104 // Restart the Glog facilities using the name `init` was provided.
105 google::InitGoogleLogging(name.c_str());
107 // We may violate Glog global object assumptions. So set names manually.
108 auto basename = (log_path_ / name).string();
110 google::SetLogDestination(google::GLOG_INFO, (basename + ".INFO.").c_str());
111 google::SetLogDestination(google::GLOG_WARNING,
112 (basename + ".WARNING.").c_str());
113 google::SetLogDestination(google::GLOG_ERROR, (basename + ".ERROR.").c_str());
115 // Store settings for logging to stderr.
116 bool log_to_stderr = FLAGS_logtostderr;
117 bool also_log_to_stderr = FLAGS_alsologtostderr;
118 int stderr_threshold = FLAGS_stderrthreshold;
119 FLAGS_alsologtostderr = false;
120 FLAGS_logtostderr = false;
121 FLAGS_stderrthreshold = 5;
123 // Now funnel the intermediate status logs provided to `init`.
126 // The filesystem logger cheats and uses Glog to log to the filesystem so
127 // we can return failure here and stop the custom log sink.
128 // Restore settings for logging to stderr.
129 FLAGS_logtostderr = log_to_stderr;
130 FLAGS_alsologtostderr = also_log_to_stderr;
131 FLAGS_stderrthreshold = stderr_threshold;