1 // Copyright 2019 Google LLC
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 "fcp/tracing/text_tracing_recorder_impl.h"
16
17 #include <memory>
18 #include <ostream>
19 #include <string>
20 #include <utility>
21
22 #include "absl/time/clock.h"
23 #include "fcp/tracing/text_tracing_span_impl.h"
24 #include "flatbuffers/minireflect.h"
25
26 namespace fcp::tracing_internal {
27
28 using std::endl;
29
TextTracingRecorderImpl(const std::string & filename,absl::TimeZone time_zone)30 TextTracingRecorderImpl::TextTracingRecorderImpl(const std::string& filename,
31 absl::TimeZone time_zone)
32 : fstream_(filename), time_zone_(time_zone) {
33 stream_ = &fstream_.value();
34 root_span_ = std::make_unique<TextTracingSpanImpl>(this);
35 }
36
TextTracingRecorderImpl(absl::TimeZone time_zone)37 TextTracingRecorderImpl::TextTracingRecorderImpl(absl::TimeZone time_zone)
38 : stream_(&std::cerr), time_zone_(time_zone) {
39 root_span_ = std::make_unique<TextTracingSpanImpl>(this);
40 }
41
42 // TODO(team): Ensure traces from different threads are not interleaved.
TraceImpl(TracingSpanId id,flatbuffers::DetachedBuffer && buf,const TracingTraitsBase & traits)43 void TextTracingRecorderImpl::TraceImpl(TracingSpanId id,
44 flatbuffers::DetachedBuffer&& buf,
45 const TracingTraitsBase& traits) {
46 LogTime();
47 *stream_ << id << ": " << TracingTraitsBase::SeverityString(traits.Severity())
48 << " " << traits.Name() << traits.TextFormat(buf) << endl;
49 }
50
BeginSpan(TracingSpanId id,TracingSpanId parent_id,absl::string_view name,absl::string_view text_format)51 void TextTracingRecorderImpl::BeginSpan(TracingSpanId id,
52 TracingSpanId parent_id,
53 absl::string_view name,
54 absl::string_view text_format) {
55 LogSpan(/* begin = */ true, id, parent_id, name, text_format);
56 }
57
EndSpan(TracingSpanId id,absl::string_view name,absl::string_view text_format)58 void TextTracingRecorderImpl::EndSpan(TracingSpanId id, absl::string_view name,
59 absl::string_view text_format) {
60 LogSpan(/* begin = */ false, id, TracingSpanId(0), name, text_format);
61 }
62
LogSpan(bool begin,TracingSpanId id,TracingSpanId parent_id,absl::string_view name,absl::string_view text_format)63 void TextTracingRecorderImpl::LogSpan(bool begin, TracingSpanId id,
64 TracingSpanId parent_id,
65 absl::string_view name,
66 absl::string_view text_format) {
67 LogTime();
68 *stream_ << id << (begin ? ": BEGIN" : ": END");
69 if (name.length() > 0) {
70 *stream_ << " " << name << " " << text_format;
71 }
72 if (begin && id != TracingSpanId(0)) {
73 *stream_ << " parent: " << parent_id;
74 }
75 *stream_ << endl;
76 }
77
LogTime()78 void TextTracingRecorderImpl::LogTime() {
79 *stream_ << absl::FormatTime(absl::Now(), time_zone_) << " ";
80 }
81
GetRootSpan()82 TracingSpanImpl* TextTracingRecorderImpl::GetRootSpan() {
83 return root_span_.get();
84 }
85
CreateChildSpan(TracingSpanId parent_span_id,flatbuffers::DetachedBuffer && buf,const TracingTraitsBase & traits)86 std::unique_ptr<TracingSpanImpl> TextTracingRecorderImpl::CreateChildSpan(
87 TracingSpanId parent_span_id, flatbuffers::DetachedBuffer&& buf,
88 const TracingTraitsBase& traits) {
89 // NOTE: shared_from_this() is defined in a base class, so it returns
90 // std::shared_ptr<TracingRecorderImpl> and we have to (safely) cast it here:
91 auto shared_this =
92 std::static_pointer_cast<TextTracingRecorderImpl>(shared_from_this());
93 return std::make_unique<TextTracingSpanImpl>(
94 shared_this, std::move(buf), traits, TracingSpanId::NextUniqueId(),
95 parent_span_id);
96 }
97
98 TextTracingRecorderImpl::~TextTracingRecorderImpl() = default;
99
100 } // namespace fcp::tracing_internal
101