12498b56bSopenharmony_ci/*
22498b56bSopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd.
32498b56bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
42498b56bSopenharmony_ci * you may not use this file except in compliance with the License.
52498b56bSopenharmony_ci * You may obtain a copy of the License at
62498b56bSopenharmony_ci *
72498b56bSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
82498b56bSopenharmony_ci *
92498b56bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
102498b56bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
112498b56bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
122498b56bSopenharmony_ci * See the License for the specific language governing permissions and
132498b56bSopenharmony_ci * limitations under the License.
142498b56bSopenharmony_ci */
152498b56bSopenharmony_ci#include "flow_control.h"
162498b56bSopenharmony_ci
172498b56bSopenharmony_ci#include <fstream>
182498b56bSopenharmony_ci#include <iostream>
192498b56bSopenharmony_ci#include <strstream>
202498b56bSopenharmony_ci#include <string>
212498b56bSopenharmony_ci#include <ctime>
222498b56bSopenharmony_ci#include <atomic>
232498b56bSopenharmony_ci#include <unordered_map>
242498b56bSopenharmony_ci#include <unistd.h>
252498b56bSopenharmony_ci#include <hilog/log.h>
262498b56bSopenharmony_ci#include "properties.h"
272498b56bSopenharmony_ci#include "log_timestamp.h"
282498b56bSopenharmony_ci#include "log_utils.h"
292498b56bSopenharmony_ci
302498b56bSopenharmony_cinamespace OHOS {
312498b56bSopenharmony_cinamespace HiviewDFX {
322498b56bSopenharmony_ciconstexpr int FLOW_CTL_NORAML = 0;
332498b56bSopenharmony_ciconstexpr int FLOW_CTL_DROPPED = -1;
342498b56bSopenharmony_ci
352498b56bSopenharmony_ciusing DomainInfo = struct {
362498b56bSopenharmony_ci    uint32_t quota;
372498b56bSopenharmony_ci    uint32_t sumLen;
382498b56bSopenharmony_ci    uint32_t dropped;
392498b56bSopenharmony_ci    LogTimeStamp startTime;
402498b56bSopenharmony_ci};
412498b56bSopenharmony_cistatic std::unordered_map<uint32_t, DomainInfo> g_domainMap;
422498b56bSopenharmony_ci
432498b56bSopenharmony_ciint FlowCtrlDomain(const HilogMsg& hilogMsg)
442498b56bSopenharmony_ci{
452498b56bSopenharmony_ci    static const LogTimeStamp PERIOD(1, 0);
462498b56bSopenharmony_ci    if (hilogMsg.type == LOG_APP) {
472498b56bSopenharmony_ci        return FLOW_CTL_NORAML;
482498b56bSopenharmony_ci    }
492498b56bSopenharmony_ci    int ret = FLOW_CTL_NORAML;
502498b56bSopenharmony_ci    uint32_t domainId = hilogMsg.domain;
512498b56bSopenharmony_ci    auto logLen = hilogMsg.len - sizeof(HilogMsg) - 1 - 1; /* quota length exclude '\0' of tag and log content */
522498b56bSopenharmony_ci    LogTimeStamp tsNow(hilogMsg.mono_sec, hilogMsg.tv_nsec);
532498b56bSopenharmony_ci    auto it = g_domainMap.find(domainId);
542498b56bSopenharmony_ci    if (it != g_domainMap.end()) {
552498b56bSopenharmony_ci        LogTimeStamp start = it->second.startTime;
562498b56bSopenharmony_ci        start += PERIOD;
572498b56bSopenharmony_ci        /* in statistic period(1 second) */
582498b56bSopenharmony_ci        if (tsNow > start) { /* new statistic period */
592498b56bSopenharmony_ci            it->second.startTime = tsNow;
602498b56bSopenharmony_ci            it->second.sumLen = logLen;
612498b56bSopenharmony_ci            ret = static_cast<int>(it->second.dropped);
622498b56bSopenharmony_ci            it->second.dropped = 0;
632498b56bSopenharmony_ci        } else {
642498b56bSopenharmony_ci            if (it->second.sumLen <= it->second.quota) { /* under quota */
652498b56bSopenharmony_ci                it->second.sumLen += logLen;
662498b56bSopenharmony_ci                ret = FLOW_CTL_NORAML;
672498b56bSopenharmony_ci            } else { /* over quota */
682498b56bSopenharmony_ci                it->second.dropped++;
692498b56bSopenharmony_ci                ret = FLOW_CTL_DROPPED;
702498b56bSopenharmony_ci            }
712498b56bSopenharmony_ci        }
722498b56bSopenharmony_ci    } else {
732498b56bSopenharmony_ci        int quota = GetDomainQuota(domainId);
742498b56bSopenharmony_ci        DomainInfo info{static_cast<uint32_t>(quota), logLen, 0, tsNow};
752498b56bSopenharmony_ci        g_domainMap.emplace(domainId, info);
762498b56bSopenharmony_ci    }
772498b56bSopenharmony_ci    return ret;
782498b56bSopenharmony_ci}
792498b56bSopenharmony_ci} // namespace HiviewDFX
802498b56bSopenharmony_ci} // namespace OHOS
81