Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4ddbef31 authored by Abhishek Pandit-Subedi's avatar Abhishek Pandit-Subedi Committed by Abhishek Pandit-Subedi
Browse files

floss: Pipe logs to syslog instead of stderr

Currently, logs just get written to stderr on Linux and don't get
captured in any logs. Change this behavior to pipe all logs to syslog
and also print to stderr (via LOG_PERROR).

Bug: 190648196
Tag: #floss
Test: Run on ChromeOS
Change-Id: Iae2ca70e38ade99c5cf8e56eedf8ea7646ac9fa4
parent e14ed674
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -18,7 +18,9 @@

#include <limits.h>
#include <string.h>

#include <charconv>
#include <chrono>
#include <iomanip>
#include <iterator>
#include <limits>
+1 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ source_set("BluetoothOsSources_linux") {
    "linux/parameter_provider.cc",
    "linux/system_properties.cc",
    "linux/wakelock_native.cc",
    "syslog.cc",
  ]

  configs += [ "//bt/gd:gd_defaults" ]
+53 −4
Original line number Diff line number Diff line
@@ -77,16 +77,65 @@ static_assert(LOG_TAG != nullptr, "LOG_TAG is null after header inclusion");
    fprintf(stderr, "%s:%d - %s: " fmt "\n", __FILE__, __LINE__, __func__, ##args); \
    abort();                                                                        \
  } while (false)
#elif defined(TARGET_FLOSS)
#include "gd/os/syslog.h"

// Prefix the log with tag, file, line and function
#define LOGWRAPPER(tag, fmt, args...) \
  write_syslog(tag, "%s:%s:%d - %s: " fmt, LOG_TAG, __FILE__, __LINE__, __func__, ##args)

#ifdef FUZZ_TARGET
#define LOG_VERBOSE(...)
#define LOG_DEBUG(...)
#define LOG_INFO(...)
#define LOG_WARN(...)
#else
/* syslog didn't work well here since we would be redefining LOG_DEBUG. */
#include <chrono>
#include <cstdio>
#include <ctime>
#define LOG_VERBOSE(...)                                                      \
  do {                                                                        \
    if (bluetooth::common::InitFlags::IsDebugLoggingEnabledForTag(LOG_TAG)) { \
      LOGWRAPPER(LOG_TAG_VERBOSE, __VA_ARGS__);                               \
    }                                                                         \
  } while (false)
#define LOG_DEBUG(...)                                                        \
  do {                                                                        \
    if (bluetooth::common::InitFlags::IsDebugLoggingEnabledForTag(LOG_TAG)) { \
      LOGWRAPPER(LOG_TAG_DEBUG, __VA_ARGS__);                                 \
    }                                                                         \
  } while (false)
#define LOG_INFO(...) LOGWRAPPER(LOG_TAG_INFO, __VA_ARGS__)
#define LOG_WARN(...) LOGWRAPPER(LOG_TAG_WARN, __VA_ARGS__)
#endif /*FUZZ_TARGET*/
#define LOG_ERROR(...) LOGWRAPPER(LOG_TAG_ERROR, __VA_ARGS__)

#define LOG_ALWAYS_FATAL(...)               \
  do {                                      \
    LOGWRAPPER(LOG_TAG_FATAL, __VA_ARGS__); \
    abort();                                \
  } while (false)

#ifndef android_errorWriteLog
#define android_errorWriteLog(tag, subTag) LOG_ERROR("ERROR tag: 0x%x, sub_tag: %s", tag, subTag)
#endif

#ifndef android_errorWriteWithInfoLog
#define android_errorWriteWithInfoLog(tag, subTag, uid, data, dataLen) \
  LOG_ERROR("ERROR tag: 0x%x, sub_tag: %s", tag, subTag)
#endif

#ifndef LOG_EVENT_INT
#define LOG_EVENT_INT(...)
#endif

#else
/* syslog didn't work well here since we would be redefining LOG_DEBUG. */
#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>

#include <chrono>
#include <cstdio>
#include <ctime>

#define LOGWRAPPER(fmt, args...)                                                                                    \
  do {                                                                                                              \
    auto _now = std::chrono::system_clock::now();                                                                   \

system/gd/os/syslog.cc

0 → 100644
+69 −0
Original line number Diff line number Diff line
/*
 * Copyright 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "gd/os/syslog.h"

#include <syslog.h>

#include <cstdarg>
#include <memory>

namespace {
#define SYSLOG_IDENT "btadapterd"

const char kSyslogIdent[] = SYSLOG_IDENT;

// Map LOG_TAG_* to syslog mappings
const int kTagMap[] = {
    /*LOG_TAG_VERBOSE=*/LOG_DEBUG,
    /*LOG_TAG_DEBUG=*/LOG_DEBUG,
    /*LOG_TAG_INFO=*/LOG_INFO,
    /*LOG_TAG_WARN=*/LOG_WARNING,
    /*LOG_TAG_ERROR=*/LOG_ERR,
    /*LOG_TAG_FATAL=*/LOG_CRIT,
};

static_assert(sizeof(kTagMap) / sizeof(kTagMap[0]) == LOG_TAG_FATAL + 1);

class SyslogWrapper {
 public:
  SyslogWrapper() {
    openlog(kSyslogIdent, LOG_CONS | LOG_NDELAY | LOG_PID | LOG_PERROR, LOG_DAEMON);
  }

  ~SyslogWrapper() {
    closelog();
  }
};

std::unique_ptr<SyslogWrapper> gSyslog;
}  // namespace

void write_syslog(int tag, const char* format, ...) {
  if (!gSyslog) {
    gSyslog = std::make_unique<SyslogWrapper>();
  }

  // I don't expect to see incorrect tags but making the check anyway so we
  // don't go out of bounds in the array above.
  tag = tag <= LOG_TAG_FATAL ? tag : LOG_TAG_ERROR;
  int level = kTagMap[tag];

  va_list args;
  va_start(args, format);
  vsyslog(level, format, args);
  va_end(args);
}

system/gd/os/syslog.h

0 → 100644
+42 −0
Original line number Diff line number Diff line
/*
 * Copyright 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#pragma once

#include <cstdarg>
#include <cstdint>

/**
 * This header is used for systems targeting syslog as their log target (i.e.
 * Floss builds).
 */

/**
 * We separately define these tags and map them to syslog levels because the
 * log headers re-define LOG_DEBUG and LOG_INFO which are already existing in
 * the syslog header. Also, LOG_TAG_VERBOSE doesn't actually exist in syslog
 * definitions and needs to be mapped to another log level.
 */
constexpr uint32_t LOG_TAG_VERBOSE = 0x0;
constexpr uint32_t LOG_TAG_DEBUG = 0x1;
constexpr uint32_t LOG_TAG_INFO = 0x2;
constexpr uint32_t LOG_TAG_WARN = 0x3;
constexpr uint32_t LOG_TAG_ERROR = 0x4;
constexpr uint32_t LOG_TAG_FATAL = 0x5;

/**
 * Write log to syslog.
 */
void write_syslog(int tag, const char* format, ...);
Loading