1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
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 #include "flow_control.h"
16
17 #include <fstream>
18 #include <iostream>
19 #include <strstream>
20 #include <string>
21 #include <ctime>
22 #include <atomic>
23 #include <unordered_map>
24 #include <unistd.h>
25 #include <hilog/log.h>
26 #include "properties.h"
27 #include "log_timestamp.h"
28 #include "log_utils.h"
29
30 namespace OHOS {
31 namespace HiviewDFX {
32 constexpr int FLOW_CTL_NORAML = 0;
33 constexpr int FLOW_CTL_DROPPED = -1;
34
35 using DomainInfo = struct {
36 uint32_t quota;
37 uint32_t sumLen;
38 uint32_t dropped;
39 LogTimeStamp startTime;
40 };
41 static std::unordered_map<uint32_t, DomainInfo> g_domainMap;
42
FlowCtrlDomain(const HilogMsg & hilogMsg)43 int FlowCtrlDomain(const HilogMsg& hilogMsg)
44 {
45 static const LogTimeStamp PERIOD(1, 0);
46 if (hilogMsg.type == LOG_APP) {
47 return FLOW_CTL_NORAML;
48 }
49 int ret = FLOW_CTL_NORAML;
50 uint32_t domainId = hilogMsg.domain;
51 auto logLen = hilogMsg.len - sizeof(HilogMsg) - 1 - 1; /* quota length exclude '\0' of tag and log content */
52 LogTimeStamp tsNow(hilogMsg.mono_sec, hilogMsg.tv_nsec);
53 auto it = g_domainMap.find(domainId);
54 if (it != g_domainMap.end()) {
55 LogTimeStamp start = it->second.startTime;
56 start += PERIOD;
57 /* in statistic period(1 second) */
58 if (tsNow > start) { /* new statistic period */
59 it->second.startTime = tsNow;
60 it->second.sumLen = logLen;
61 ret = static_cast<int>(it->second.dropped);
62 it->second.dropped = 0;
63 } else {
64 if (it->second.sumLen <= it->second.quota) { /* under quota */
65 it->second.sumLen += logLen;
66 ret = FLOW_CTL_NORAML;
67 } else { /* over quota */
68 it->second.dropped++;
69 ret = FLOW_CTL_DROPPED;
70 }
71 }
72 } else {
73 int quota = GetDomainQuota(domainId);
74 DomainInfo info{static_cast<uint32_t>(quota), logLen, 0, tsNow};
75 g_domainMap.emplace(domainId, info);
76 }
77 return ret;
78 }
79 } // namespace HiviewDFX
80 } // namespace OHOS
81