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 30namespace OHOS { 31namespace HiviewDFX { 32constexpr int FLOW_CTL_NORAML = 0; 33constexpr int FLOW_CTL_DROPPED = -1; 34 35using DomainInfo = struct { 36 uint32_t quota; 37 uint32_t sumLen; 38 uint32_t dropped; 39 LogTimeStamp startTime; 40}; 41static std::unordered_map<uint32_t, DomainInfo> g_domainMap; 42 43int 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