Coverage Report

Created: 2026-07-16 06:49

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/hothd/log_collector_util.hpp
Line
Count
Source
1
// Copyright 2024 Google LLC
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
#pragma once
16
17
#include "google3/host_commands.h"
18
19
#include "message_util.hpp"
20
21
#include <fmt/format.h>
22
23
#include <stdplus/raw.hpp>
24
25
#include <algorithm>
26
#include <chrono>
27
#include <condition_variable>
28
#include <cstdint>
29
#include <cstring>
30
#include <functional>
31
#include <iostream>
32
#include <mutex>
33
#include <optional>
34
#include <queue>
35
#include <thread>
36
#include <unordered_map>
37
38
constexpr int kTransactionBufferSize = 1024;
39
constexpr int kBufferReadTimeoutMs = 1000;
40
constexpr int kMaxReadBufferIterations = 35;
41
constexpr bool kDebug = false;
42
constexpr int kHothBufferSize = 4096;
43
constexpr int kRateLimiterMilliSeconds = 500;
44
constexpr int kTransactionTimeoutInMicroSec = 1000;
45
constexpr int kMaxFileSizeInBytes = 4 * 1024 * 1024; // 4 MB in bytes
46
constexpr int kAsyncWaitTimeInSeconds = 30;
47
constexpr int kHeartBeatUpperLimit = 25;
48
const std::string kSyslogFileNamePrefix = "/tmp/syslog_file_";
49
50
// This is required to get a read-offset that is guaranteed to be out of the
51
// Hoth buffer, thus clients can offset the write-buffer with a big-enough value
52
// and let Hoth point to the correct read-offset.
53
// Use the same value as the upstreamed libhoth/htool:
54
// https://github.com/google/libhoth/commit/e4827163741e0804f12ac96c81b8e97649be6795
55
constexpr uint32_t kReadOffsetTweak = 0x80000000;
56
57
namespace google
58
{
59
namespace hoth
60
{
61
namespace internal
62
{
63
enum class PublishType : uint8_t
64
{
65
    Stderr,
66
    File
67
};
68
69
/**
70
 * @brief Supports rate limit for a single threaded mechanism, where requests
71
 * are discarded when the elapsed time < rate limit time
72
 */
73
class RateLimiter
74
{
75
  public:
76
    explicit RateLimiter(int rateLimitInMilliseconds) :
77
        rateLimitInMilliseconds(rateLimitInMilliseconds)
78
0
    {
79
0
        std::chrono::hours one_day(24);
80
0
        std::chrono::steady_clock::time_point yesterday =
81
0
            std::chrono::steady_clock::now() - one_day;
82
0
        lastTimeStamp = yesterday;
83
0
    };
84
85
    bool allowedByLimiter()
86
0
    {
87
0
        auto now = std::chrono::steady_clock::now();
88
0
        auto timeElapsed = now - lastTimeStamp;
89
0
        if (timeElapsed > std::chrono::milliseconds(rateLimitInMilliseconds))
90
0
        {
91
0
            lastTimeStamp = now;
92
0
            return true;
93
0
        }
94
0
        return false;
95
0
    };
96
97
    std::chrono::steady_clock::time_point getTimeStamp()
98
0
    {
99
0
        return lastTimeStamp;
100
0
    }
101
102
  private:
103
    int rateLimitInMilliseconds;
104
    std::chrono::steady_clock::time_point lastTimeStamp;
105
};
106
107
class LogCollectorUtil
108
{
109
  public:
110
    LogCollectorUtil(RateLimiter& rateLimiter, int asyncWaitTime);
111
112
    ~LogCollectorUtil() = default;
113
    /**
114
     * @brief Generates a request for snapshotting hoth buffer
115
     *
116
     * @return request as a vector of bytes
117
     */
118
    static std::vector<uint8_t> generateSnapshotRequest();
119
120
    /**
121
     * @brief Generates a request for getting the snapshot of the hoth buffer
122
     *
123
     * @return request as a vector of bytes
124
     */
125
    static std::vector<uint8_t> generateGrabSnapshotRequest();
126
127
    /**
128
     * @brief Verifies the response header
129
     *
130
     * @return true or false (in terms of validity)
131
     */
132
    static bool isResponseValid(std::vector<uint8_t> response);
133
134
    /**
135
     * @brief Generates Collect Uart Request
136
     *
137
     * @param[in] channelId - Channel Id for Uart
138
     * @param[in] readOffset - Offset from where the buffer is to be read
139
     */
140
    static std::vector<uint8_t> generateCollectUartLogsRequest(
141
        uint32_t channelId, uint32_t readOffset);
142
143
    /**
144
     * @brief Publishes the snapshot based on publish type
145
     *
146
     * @param[in] response - Response vector
147
     * @param[in] publishType - Stderr or file
148
     * @param[in] filePathSuffix - File path name suffix if Publish type is file
149
     * @param[in] meta - If any meta data is to be printed in the logs
150
     *
151
     */
152
    static void publishSnapshot(
153
        std::vector<uint8_t> response, PublishType publishType,
154
        std::string_view filePathSuffix = "", std::string_view meta = "");
155
156
    /**
157
     * @brief Generate unique request id
158
     *
159
     * @return request id
160
     */
161
    int generateRequestId();
162
163
    /**
164
     * @brief Gets the wait time set during initialization
165
     *
166
     * @return wait time in seconds
167
     */
168
    int getAsyncWaitTime() const;
169
170
    /**
171
     * @brief Current request counter
172
     */
173
    int requestCounter = 0;
174
175
    /**
176
     * @brief Create GetChannelWriteOffset request
177
     *
178
     * @param[in] channelId - Unique channel id
179
     *
180
     * @return request bytes for channel write offset
181
     */
182
    static std::vector<uint8_t> generateGetChannelWriteOffsetRequest(
183
        const uint32_t& channelId);
184
185
    /**
186
     * @brief Writes to file
187
     *
188
     * @param[in] data - string of data to be dumped in a file
189
     * @param[in] name - suffix of the file name (gets attached to prefix -
190
     * "syslog_file")
191
     */
192
    static void writeToFile(std::string_view data, std::string_view name);
193
194
    /**
195
     * @brief Sends a heartbeat once every kHeartBeatLimit when invoked
196
     *
197
     * @param[in] data - Message for the heartbeat
198
     */
199
    static void heartbeat(std::string_view message);
200
201
    /**
202
     * @brief Rate Limits the requests to be sent to log collector
203
     */
204
    RateLimiter rateLimiter;
205
206
    /**
207
     * @brief Async wait timer for uart logs
208
     */
209
    int asyncWaitTime = 0;
210
};
211
212
} // namespace internal
213
} // namespace hoth
214
} // namespace google