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 
16 #ifndef DDS_TRACE_H
17 #define DDS_TRACE_H
18 
19 #include <atomic>
20 #include <cinttypes>
21 #include <string>
22 #include <functional>
23 #include <chrono>
24 #include "hitrace/trace.h"
25 #include "hitrace_meter.h"
26 namespace OHOS {
27 namespace DistributedDataDfx {
28 enum TraceSwitch {
29     DEBUG_CLOSE = 0x00,
30     BYTRACE_ON = 0x01,
31     API_PERFORMANCE_TRACE_ON = 0x02,
32     TRACE_CHAIN_ON = 0x04,
33 };
34 class __attribute__((visibility("hidden"))) DdsTrace {
35 public:
36     using Action = std::function<void(const std::string &value, uint64_t delta)>;
37     using System = std::chrono::system_clock;
38     DdsTrace(const std::string &value, unsigned int option = BYTRACE_ON, Action action = nullptr)
39     {
40         traceSwitch_ = option;
41         traceValue_ = value;
42         action_ = action;
43         static std::atomic_bool enable = false;
44         if (!enable.exchange(true)) {
45             UpdateTraceLabel();
46         }
47         Start(value);
48     }
49 
~DdsTrace()50     ~DdsTrace()
51     {
52         Finish(traceValue_);
53     }
54 
55 private:
Start(const std::string & value)56     void Start(const std::string &value)
57     {
58         if ((traceSwitch_ & BYTRACE_ON) == BYTRACE_ON) {
59             StartTrace(HITRACE_TAG_DISTRIBUTEDDATA, value);
60         }
61         if ((traceSwitch_ & TRACE_CHAIN_ON) == TRACE_CHAIN_ON) {
62             traceId_ = OHOS::HiviewDFX::HiTraceChain::Begin(value, HITRACE_FLAG_DEFAULT);
63         }
64         if ((traceSwitch_ & API_PERFORMANCE_TRACE_ON) == API_PERFORMANCE_TRACE_ON) {
65             lastTime_ = System::now();
66         }
67     }
Finish(const std::string & value)68     void Finish(const std::string &value)
69     {
70         if ((traceSwitch_ & BYTRACE_ON) == BYTRACE_ON) {
71             FinishTrace(HITRACE_TAG_DISTRIBUTEDDATA);
72         }
73         if ((traceSwitch_ & TRACE_CHAIN_ON) == TRACE_CHAIN_ON) {
74             OHOS::HiviewDFX::HiTraceChain::End(traceId_);
75         }
76         if ((traceSwitch_ & API_PERFORMANCE_TRACE_ON) == API_PERFORMANCE_TRACE_ON && action_) {
77             action_(value, std::chrono::duration_cast<std::chrono::milliseconds>(System::now() - lastTime_).count());
78         }
79     }
80     Action action_;
81     std::string traceValue_{ };
82     HiviewDFX::HiTraceId traceId_;
83     uint32_t traceSwitch_{ 0 };
84     System::time_point lastTime_;
85 };
86 } // namespace DistributedDataDfx
87 } // namespace OHOS
88 #endif
89