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

Commit d5b3838d authored by Tom Cherry's avatar Tom Cherry
Browse files

logd: make LogBuffer an interface

We may use different implementations of LogBuffer in the future, so we
make it interface and create a concrete ChattyLogBuffer class that
implements it.

Test: logging unit tests
Change-Id: I5731d6404640664c9acc26b7c677dff3110c6a11
parent 68630a0d
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -33,12 +33,12 @@ cc_library_static {

    srcs: [
        "LogCommand.cpp",
        "ChattyLogBuffer.cpp",
        "CommandListener.cpp",
        "LogListener.cpp",
        "LogReader.cpp",
        "LogReaderList.cpp",
        "LogReaderThread.cpp",
        "LogBuffer.cpp",
        "LogBufferElement.cpp",
        "LogStatistics.cpp",
        "LogWhiteBlackList.cpp",
+73 −104

File changed and moved.

Preview size limit exceeded, changes collapsed.

logd/ChattyLogBuffer.h

0 → 100644
+97 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2012-2014 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 <sys/types.h>

#include <list>
#include <optional>
#include <string>

#include <android/log.h>
#include <private/android_filesystem_config.h>
#include <sysutils/SocketClient.h>

#include "LogBuffer.h"
#include "LogBufferElement.h"
#include "LogStatistics.h"
#include "LogTags.h"
#include "LogWhiteBlackList.h"

typedef std::list<LogBufferElement*> LogBufferElementCollection;

class LogReaderList;
class LogReaderThread;

class ChattyLogBuffer : public LogBuffer {
    LogBufferElementCollection mLogElements;
    pthread_rwlock_t mLogElementsLock;

    // watermark of any worst/chatty uid processing
    typedef std::unordered_map<uid_t, LogBufferElementCollection::iterator> LogBufferIteratorMap;
    LogBufferIteratorMap mLastWorst[LOG_ID_MAX];
    // watermark of any worst/chatty pid of system processing
    typedef std::unordered_map<pid_t, LogBufferElementCollection::iterator> LogBufferPidIteratorMap;
    LogBufferPidIteratorMap mLastWorstPidOfSystem[LOG_ID_MAX];

    unsigned long mMaxSize[LOG_ID_MAX];

    LogBufferElement* lastLoggedElements[LOG_ID_MAX];
    LogBufferElement* droppedElements[LOG_ID_MAX];
    void log(LogBufferElement* elem);

  public:
    ChattyLogBuffer(LogReaderList* reader_list, LogTags* tags, PruneList* prune,
                    LogStatistics* stats);
    ~ChattyLogBuffer();
    void Init() override;

    int Log(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid, pid_t tid, const char* msg,
            uint16_t len) override;
    uint64_t FlushTo(
            SocketClient* writer, uint64_t start, pid_t* lastTid, bool privileged, bool security,
            const std::function<FlushToResult(const LogBufferElement* element)>& filter) override;

    bool Clear(log_id_t id, uid_t uid = AID_ROOT) override;
    unsigned long GetSize(log_id_t id) override;
    int SetSize(log_id_t id, unsigned long size) override;

  private:
    void wrlock() { pthread_rwlock_wrlock(&mLogElementsLock); }
    void rdlock() { pthread_rwlock_rdlock(&mLogElementsLock); }
    void unlock() { pthread_rwlock_unlock(&mLogElementsLock); }

    void maybePrune(log_id_t id);
    void kickMe(LogReaderThread* me, log_id_t id, unsigned long pruneRows);

    bool prune(log_id_t id, unsigned long pruneRows, uid_t uid = AID_ROOT);
    LogBufferElementCollection::iterator erase(LogBufferElementCollection::iterator it,
                                               bool coalesce = false);

    // Returns an iterator to the oldest element for a given log type, or mLogElements.end() if
    // there are no logs for the given log type. Requires mLogElementsLock to be held.
    LogBufferElementCollection::iterator GetOldest(log_id_t log_id);

    LogReaderList* reader_list_;
    LogTags* tags_;
    PruneList* prune_;
    LogStatistics* stats_;

    // Keeps track of the iterator to the oldest log message of a given log type, as an
    // optimization when pruning logs.  Use GetOldest() to retrieve.
    std::optional<LogBufferElementCollection::iterator> oldest_[LOG_ID_MAX];
};
+4 −4
Original line number Diff line number Diff line
@@ -81,7 +81,7 @@ int CommandListener::ClearCmd::runCommand(SocketClient* cli, int argc,
        return 0;
    }

    cli->sendMsg(buf()->clear((log_id_t)id, uid) ? "busy" : "success");
    cli->sendMsg(buf()->Clear((log_id_t)id, uid) ? "busy" : "success");
    return 0;
}

@@ -99,7 +99,7 @@ int CommandListener::GetBufSizeCmd::runCommand(SocketClient* cli, int argc,
        return 0;
    }

    unsigned long size = buf()->getSize((log_id_t)id);
    unsigned long size = buf()->GetSize((log_id_t)id);
    char buf[512];
    snprintf(buf, sizeof(buf), "%lu", size);
    cli->sendMsg(buf);
@@ -126,7 +126,7 @@ int CommandListener::SetBufSizeCmd::runCommand(SocketClient* cli, int argc,
    }

    unsigned long size = atol(argv[2]);
    if (buf()->setSize((log_id_t)id, size)) {
    if (buf()->SetSize((log_id_t)id, size)) {
        cli->sendMsg("Range Error");
        return 0;
    }
@@ -299,7 +299,7 @@ int CommandListener::ReinitCmd::runCommand(SocketClient* cli, int /*argc*/,
    setname();

    android::prdebug("logd reinit");
    buf()->init();
    buf()->Init();
    prune()->init(nullptr);

    // This only works on userdebug and eng devices to re-read the
+4 −6
Original line number Diff line number Diff line
@@ -274,8 +274,7 @@ int LogAudit::logPrint(const char* fmt, ...) {
        memcpy(event->data + str_len - denial_metadata.length(),
               denial_metadata.c_str(), denial_metadata.length());

        rc = logbuf->log(
            LOG_ID_EVENTS, now, uid, pid, tid, reinterpret_cast<char*>(event),
        rc = logbuf->Log(LOG_ID_EVENTS, now, uid, pid, tid, reinterpret_cast<char*>(event),
                         (message_len <= UINT16_MAX) ? (uint16_t)message_len : UINT16_MAX);
        if (rc >= 0) {
            notify |= 1 << LOG_ID_EVENTS;
@@ -328,8 +327,7 @@ int LogAudit::logPrint(const char* fmt, ...) {
        strncpy(newstr + 1 + str_len + prefix_len + suffix_len,
                denial_metadata.c_str(), denial_metadata.length());

        rc = logbuf->log(
            LOG_ID_MAIN, now, uid, pid, tid, newstr,
        rc = logbuf->Log(LOG_ID_MAIN, now, uid, pid, tid, newstr,
                         (message_len <= UINT16_MAX) ? (uint16_t)message_len : UINT16_MAX);

        if (rc >= 0) {
Loading