blob: ad2ca0a87a99af309572c721bad00bd60ae53086 [file] [log] [blame]
// Copyright 2017 The Chromium OS 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 VM_TOOLS_SYSLOG_COLLECTOR_H_
#define VM_TOOLS_SYSLOG_COLLECTOR_H_
#include <memory>
#include <base/callback.h>
#include <base/files/file_descriptor_watcher_posix.h>
#include <base/files/scoped_file.h>
#include <base/macros.h>
#include <base/memory/weak_ptr.h>
#include <base/time/time.h>
#include <base/timer/timer.h>
#include <google/protobuf/arena.h>
#include <vm_protos/proto_bindings/vm_host.grpc.pb.h>
namespace vm_tools {
namespace syslog {
// Responsible for listening on /dev/log for any userspace applications that
// wish to log messages with the system syslog. TODO(chirantan): This
// currently doesn't handle kernel oops or flushing during shutdown.
class Collector {
public:
// Create a new, initialized Collector.
static std::unique_ptr<Collector> Create(base::Closure shutdown_closure);
~Collector() = default;
static std::unique_ptr<Collector> CreateForTesting(
base::ScopedFD syslog_fd,
base::Time boot_time,
std::unique_ptr<vm_tools::LogCollector::Stub> stub);
private:
// Private default constructor. Use the static factory function to create new
// instances of this class.
explicit Collector(base::Closure shutdown_closure);
// Initializes this Collector. Starts listening on the syslog socket
// and sets up timers to periodically flush logs out.
bool Init();
// Called periodically to flush any logs that have been buffered.
void FlushLogs();
// Reads one log record from the socket and adds it to |syslog_request_|.
// Returns true if there may still be more data to read from the socket.
bool ReadOneSyslogRecord();
// Initializes this Collector for tests. Starts listening on the
// provided file descriptor instead of creating a socket and binding to a
// path on the file system.
bool InitForTesting(base::ScopedFD syslog_fd,
base::Time boot_time,
std::unique_ptr<vm_tools::LogCollector::Stub> stub);
// Called when |syslog_fd_| becomes readable.
void OnSyslogReadable();
// Called when |signal_fd_| becomes readable.
void OnSignalReadable();
// File descriptor bound to /dev/log.
base::ScopedFD syslog_fd_;
std::unique_ptr<base::FileDescriptorWatcher::Controller> syslog_controller_;
// File descriptor for receiving signals.
base::ScopedFD signal_fd_;
std::unique_ptr<base::FileDescriptorWatcher::Controller> signal_controller_;
// Closure for stopping the MessageLoop. Posted to the thread's TaskRunner
// when this program receives a SIGTERM.
base::Closure shutdown_closure_;
// Time that the VM booted. Used to convert kernel timestamps to localtime.
base::Time boot_time_;
// Shared arena used for allocating log records.
google::protobuf::Arena arena_;
// Non-owning pointer to the current syslog LogRequest. Owned by arena_.
vm_tools::LogRequest* syslog_request_;
// Size of all the currently buffered log records.
size_t buffered_size_;
// Connection to the LogCollector service on the host.
std::unique_ptr<vm_tools::LogCollector::Stub> stub_;
// Timer used for periodically flushing buffered log records.
base::RepeatingTimer timer_;
base::WeakPtrFactory<Collector> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(Collector);
};
} // namespace syslog
} // namespace vm_tools
#endif // VM_TOOLS_SYSLOG_COLLECTOR_H_