blob: c4fb3a5d7af6e31bbf08c312f9999ec43128e904 [file] [log] [blame]
// Copyright 2020 The Fuchsia 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 <fuchsia/validate/logs/cpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/fidl/cpp/binding_set.h>
#include <lib/sys/cpp/component_context.h>
#include <lib/syslog/cpp/macros.h>
#include "lib/syslog/cpp/log_level.h"
#include "lib/syslog/cpp/log_settings.h"
zx_koid_t GetKoid(zx_handle_t handle) {
zx_info_handle_basic_t info;
zx_status_t status =
zx_object_get_info(handle, ZX_INFO_HANDLE_BASIC, &info, sizeof(info), nullptr, nullptr);
return status == ZX_OK ? info.koid : ZX_KOID_INVALID;
}
class Puppet : public fuchsia::validate::logs::LogSinkPuppet {
public:
explicit Puppet(std::unique_ptr<sys::ComponentContext> context) : context_(std::move(context)) {
context_->outgoing()->AddPublicService(sink_bindings_.GetHandler(this));
}
void GetInfo(GetInfoCallback callback) override {
fuchsia::validate::logs::PuppetInfo info;
info.pid = GetKoid(zx_process_self());
info.tid = GetKoid(zx_thread_self());
callback(info);
}
void EmitLog(fuchsia::validate::logs::RecordSpec spec, EmitLogCallback callback) override {
if (fuchsia_logging::IsSeverityEnabled(spec.record.severity)) {
auto builder = fuchsia_logging::LogBufferBuilder(static_cast<uint8_t>(spec.record.severity));
auto buffer = builder.WithFile(spec.file, spec.line).Build();
for (auto& arg : spec.record.arguments) {
switch (arg.value.Which()) {
case fuchsia::validate::logs::Value::kUnknown:
case fuchsia::validate::logs::Value::Invalid:
break;
case fuchsia::validate::logs::Value::kFloating:
buffer.WriteKeyValue(arg.name, arg.value.floating());
break;
case fuchsia::validate::logs::Value::kSignedInt:
buffer.WriteKeyValue(arg.name, arg.value.signed_int());
break;
case fuchsia::validate::logs::Value::kUnsignedInt:
buffer.WriteKeyValue(arg.name, arg.value.unsigned_int());
break;
case fuchsia::validate::logs::Value::kText:
buffer.WriteKeyValue(arg.name, arg.value.text().data());
break;
case fuchsia::validate::logs::Value::kBoolean:
buffer.WriteKeyValue(arg.name, arg.value.boolean());
break;
}
}
[[maybe_unused]] zx::result<> result = fuchsia_logging::FlushToGlobalLogger(buffer);
}
callback();
}
private:
std::unique_ptr<sys::ComponentContext> context_;
fidl::BindingSet<fuchsia::validate::logs::LogSinkPuppet> sink_bindings_;
};
int main(int argc, const char** argv) {
async::Loop loop(&kAsyncLoopConfigAttachToCurrentThread);
fuchsia_logging::LogSettingsBuilder log_settings;
log_settings.WithDispatcher(loop.dispatcher())
.WithSeverityChangedListener(
nullptr, +[](void*, fuchsia_logging::RawLogSeverity severity) {
auto builder = fuchsia_logging::LogBufferBuilder(severity);
auto buffer = builder.WithFile(__FILE__, __LINE__).WithMsg("Changed severity").Build();
[[maybe_unused]] zx::result<> result = fuchsia_logging::FlushToGlobalLogger(buffer);
});
log_settings.BuildAndInitialize();
Puppet puppet(sys::ComponentContext::CreateAndServeOutgoingDirectory());
// Note: This puppet is ran by a runner that
// uses --test-invalid-unicode, which isn't directly passed to this puppet
// but tells the Rust puppet runner that we are sending invalid UTF-8.
FX_LOGS(INFO) << "Puppet started.\xc3\x28";
loop.Run();
}