0

Adds new logging type SYSLOG which logs to the system log.

On Windows this type logs to the Event Log and on POSIX systems it logs to the messages log (or its equvalent).

As a side effect of adding the presubmit check for it this
CL fixes running the presumbit checks tests on Windows.

BUG=642115

Review-Url: https://codereview.chromium.org/2296783002
Cr-Commit-Position: refs/heads/master@{#419758}
This commit is contained in:
pastarmovj
2016-09-20 07:58:13 -07:00
committed by Commit bot
parent 76ad59ea95
commit 89f7ee10f0
7 changed files with 175 additions and 0 deletions

@ -2215,6 +2215,20 @@ def _CheckForWindowsLineEndings(input_api, output_api):
return []
def _CheckSyslogUseWarning(input_api, output_api, source_file_filter=None,
lint_filters=None, verbose_level=None):
"""Checks that all source files use SYSLOG properly."""
syslog_files = []
for f in input_api.AffectedSourceFiles(source_file_filter):
if 'SYSLOG' in input_api.ReadFile(f, 'rb'):
syslog_files.append(f.LocalPath())
if syslog_files:
return [output_api.PresubmitPromptWarning(
'Please make sure there are no privacy sensitive bits of data in SYSLOG'
' calls.\nFiles to check:\n', items=syslog_files)]
return []
def CheckChangeOnUpload(input_api, output_api):
results = []
results.extend(_CommonChecks(input_api, output_api))
@ -2223,6 +2237,7 @@ def CheckChangeOnUpload(input_api, output_api):
input_api.canned_checks.CheckGNFormatted(input_api, output_api))
results.extend(_CheckUmaHistogramChanges(input_api, output_api))
results.extend(_AndroidSpecificOnUploadChecks(input_api, output_api))
results.extend(_CheckSyslogUseWarning(input_api, output_api))
return results

@ -866,6 +866,10 @@ class PydepsNeedsUpdatingTest(unittest.TestCase):
checker_for_tests=self.checker)
def testAddedPydep(self):
# PRESUBMIT._CheckPydepsNeedsUpdating is only implemented for Android.
if self.mock_input_api.platform != 'linux2':
return []
self.mock_input_api.files = [
MockAffectedFile('new.pydeps', [], action='A'),
]
@ -875,6 +879,10 @@ class PydepsNeedsUpdatingTest(unittest.TestCase):
self.assertTrue('PYDEPS_FILES' in str(results[0]))
def testRemovedPydep(self):
# PRESUBMIT._CheckPydepsNeedsUpdating is only implemented for Android.
if self.mock_input_api.platform != 'linux2':
return []
self.mock_input_api.files = [
MockAffectedFile(PRESUBMIT._ALL_PYDEPS_FILES[0], [], action='D'),
]
@ -884,6 +892,10 @@ class PydepsNeedsUpdatingTest(unittest.TestCase):
self.assertTrue('PYDEPS_FILES' in str(results[0]))
def testRandomPyIgnored(self):
# PRESUBMIT._CheckPydepsNeedsUpdating is only implemented for Android.
if self.mock_input_api.platform != 'linux2':
return []
self.mock_input_api.files = [
MockAffectedFile('random.py', []),
]
@ -892,6 +904,10 @@ class PydepsNeedsUpdatingTest(unittest.TestCase):
self.assertEqual(0, len(results), 'Unexpected results: %r' % results)
def testRelevantPyNoChange(self):
# PRESUBMIT._CheckPydepsNeedsUpdating is only implemented for Android.
if self.mock_input_api.platform != 'linux2':
return []
self.mock_input_api.files = [
MockAffectedFile('A.py', []),
]
@ -906,6 +922,10 @@ class PydepsNeedsUpdatingTest(unittest.TestCase):
self.assertEqual(0, len(results), 'Unexpected results: %r' % results)
def testRelevantPyOneChange(self):
# PRESUBMIT._CheckPydepsNeedsUpdating is only implemented for Android.
if self.mock_input_api.platform != 'linux2':
return []
self.mock_input_api.files = [
MockAffectedFile('A.py', []),
]
@ -921,6 +941,10 @@ class PydepsNeedsUpdatingTest(unittest.TestCase):
self.assertTrue('File is stale' in str(results[0]))
def testRelevantPyTwoChanges(self):
# PRESUBMIT._CheckPydepsNeedsUpdating is only implemented for Android.
if self.mock_input_api.platform != 'linux2':
return []
self.mock_input_api.files = [
MockAffectedFile('C.py', []),
]

@ -22,6 +22,7 @@ class MockInputApi(object):
self.os_path = os.path
self.platform = sys.platform
self.python_executable = sys.executable
self.platform = sys.platform
self.subprocess = subprocess
self.files = []
self.is_committing = False
@ -122,6 +123,10 @@ class MockFile(object):
"""os.path.basename is called on MockFile so we need a get method."""
return self._local_path[i]
def __len__(self):
"""os.path.basename is called on MockFile so we need a len method."""
return len(self._local_path)
class MockAffectedFile(MockFile):
def AbsoluteLocalPath(self):

@ -770,6 +770,8 @@ component("base") {
"sys_info.h",
"sys_info_android.cc",
"sys_info_chromeos.cc",
"syslog_logging.cc",
"syslog_logging.h",
#"sys_info_freebsd.cc", # Unused in Chromium build.
"sys_info_ios.mm",

@ -795,6 +795,9 @@ class BASE_EXPORT LogMessage {
std::ostream& stream() { return stream_; }
LogSeverity severity() { return severity_; }
std::string str() { return stream_.str(); }
private:
void Init(const char* file, int line);

88
base/syslog_logging.cc Normal file

@ -0,0 +1,88 @@
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/debug/stack_trace.h"
#include "base/syslog_logging.h"
#if defined(OS_WIN)
#include <windows.h>
#elif defined(OS_LINUX)
#include <syslog.h>
#endif
#include <cstring>
#include <ostream>
#include <string>
namespace logging {
EventLogMessage::EventLogMessage(const char* file,
int line,
LogSeverity severity)
: log_message_(file, line, severity) {
}
EventLogMessage::~EventLogMessage() {
#if defined(OS_WIN)
const char kEventSource[] = "chrome";
HANDLE event_log_handle = RegisterEventSourceA(NULL, kEventSource);
if (event_log_handle == NULL) {
stream() << " !!NOT ADDED TO EVENTLOG!!";
return;
}
std::string message(log_message_.str());
LPCSTR strings[1] = {message.data()};
WORD log_type = EVENTLOG_ERROR_TYPE;
switch (log_message_.severity()) {
case LOG_INFO:
log_type = EVENTLOG_INFORMATION_TYPE;
break;
case LOG_WARNING:
log_type = EVENTLOG_WARNING_TYPE;
break;
case LOG_ERROR:
case LOG_FATAL:
// The price of getting the stack trace is not worth the hassle for
// non-error conditions.
base::debug::StackTrace trace;
message.append(trace.ToString());
log_type = EVENTLOG_ERROR_TYPE;
break;
}
// TODO(pastarmovj): Register Chrome's event log resource types to make the
// entries nicer. 1337 is just a made up event id type.
if (!ReportEventA(event_log_handle, log_type, 0, 1337, NULL, 1, 0,
strings, NULL)) {
stream() << " !!NOT ADDED TO EVENTLOG!!";
}
DeregisterEventSource(event_log_handle);
#elif defined(OS_LINUX)
const char kEventSource[] = "chrome";
openlog(kEventSource, LOG_NOWAIT | LOG_PID, LOG_USER);
// We can't use the defined names for the logging severity from syslog.h
// because they collide with the names of our own severity levels. Therefore
// we use the actual values which of course do not match ours.
// See sys/syslog.h for reference.
int priority = 3;
switch (log_message_.severity()) {
case LOG_INFO:
priority = 6;
break;
case LOG_WARNING:
priority = 4;
break;
case LOG_ERROR:
priority = 3;
break;
case LOG_FATAL:
priority = 2;
break;
}
syslog(priority, "%s", log_message_.str().c_str());
closelog();
#endif // defined(OS_WIN)
}
} // namespace logging

38
base/syslog_logging.h Normal file

@ -0,0 +1,38 @@
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef BASE_SYSLOG_LOGGING_H_
#define BASE_SYSLOG_LOGGING_H_
#include "base/logging.h"
namespace logging {
// Keep in mind that the syslog is always active regardless of the logging level
// and applied flags. Use only for important information that a system
// administrator might need to maintain the browser installation.
#define SYSLOG_STREAM(severity) \
COMPACT_GOOGLE_LOG_EX_ ## severity(EventLogMessage).stream()
#define SYSLOG(severity) \
SYSLOG_STREAM(severity)
// Creates a formatted message on the system event log. That would be the
// Application Event log on Windows and the messages log file on POSIX systems.
class BASE_EXPORT EventLogMessage {
public:
EventLogMessage(const char* file, int line, LogSeverity severity);
~EventLogMessage();
std::ostream& stream() { return log_message_.stream(); }
private:
LogMessage log_message_;
DISALLOW_COPY_AND_ASSIGN(EventLogMessage);
};
} // namespace logging
#endif // BASE_SYSLOG_LOGGING_H_