1 // Copyright (C) 2023 The Android Open Source Project
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 #include <ditto/logger.h>
16 #include <ditto/tracer.h>
17
18 #include <google/protobuf/util/json_util.h>
19
20 #include <cstdarg>
21 #include <unistd.h>
22
23 namespace dittosuite {
24
random_string(int len)25 std::string random_string(int len) {
26 std::string char_set;
27 for (char c = '0'; c <= '9'; ++c) {
28 char_set += c;
29 }
30 for (char c = 'a'; c <= 'z'; ++c) {
31 char_set += c;
32 }
33 for (char c = 'A'; c <= 'Z'; ++c) {
34 char_set += c;
35 }
36
37 std::string ret;
38
39 ret.reserve(len);
40 for (int i = 0; i < len; ++i) {
41 ret += char_set[rand() % (char_set.length())];
42 }
43
44 return ret;
45 }
46
StartSession(std::unique_ptr<dittosuiteproto::Benchmark> benchmark)47 void Tracer::StartSession(std::unique_ptr<dittosuiteproto::Benchmark> benchmark) {
48 if (!trace_marker_.good()) {
49 return;
50 }
51
52 std::string benchmark_dump;
53 google::protobuf::util::JsonPrintOptions options;
54
55 auto status = google::protobuf::util::MessageToJsonString(*benchmark, &benchmark_dump, options);
56
57 if (!status.ok()) {
58 LOGF("Unable to dump benchmark into string");
59 }
60
61 id_ = random_string(16);
62
63 trace_marker_ << trace_format("B", std::to_string(getpid()), "Session", benchmark_dump, id_);
64 trace_marker_.write("\0", 1);
65 trace_marker_.flush();
66 }
67
Start(const std::string & splice)68 void Tracer::Start(const std::string& splice) {
69 if (!trace_marker_.good()) {
70 return;
71 }
72
73 trace_marker_ << trace_format("B", std::to_string(getpid()), splice);
74 trace_marker_.write("\0", 1);
75 trace_marker_.flush();
76 }
77
End(const std::string & splice)78 void Tracer::End(const std::string& splice) {
79 if (!trace_marker_.good()) {
80 return;
81 }
82
83 trace_marker_ << trace_format("E", std::to_string(getpid()), splice);
84 trace_marker_.write("\0", 1);
85 trace_marker_.flush();
86 }
87
Tracer()88 Tracer::Tracer() {
89 trace_marker_.open("/sys/kernel/tracing/trace_marker",
90 std::ofstream::out | std::ofstream::binary);
91 if (!trace_marker_.good()) {
92 LOGW("Unable to open trace_marker");
93 }
94 }
95
~Tracer()96 Tracer::~Tracer() {
97 if (!trace_marker_.good()) {
98 return;
99 }
100
101 trace_marker_ << trace_format("E", std::to_string(getpid()), "Session", id_);
102 trace_marker_.write("\0", 1);
103 trace_marker_.flush();
104
105 trace_marker_.close();
106 }
107
108 } // namespace dittosuite
109