// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include "fcp/tracing/text_tracing_recorder_impl.h" #include #include #include #include #include "absl/time/clock.h" #include "fcp/tracing/text_tracing_span_impl.h" #include "flatbuffers/minireflect.h" namespace fcp::tracing_internal { using std::endl; TextTracingRecorderImpl::TextTracingRecorderImpl(const std::string& filename, absl::TimeZone time_zone) : fstream_(filename), time_zone_(time_zone) { stream_ = &fstream_.value(); root_span_ = std::make_unique(this); } TextTracingRecorderImpl::TextTracingRecorderImpl(absl::TimeZone time_zone) : stream_(&std::cerr), time_zone_(time_zone) { root_span_ = std::make_unique(this); } // TODO(team): Ensure traces from different threads are not interleaved. void TextTracingRecorderImpl::TraceImpl(TracingSpanId id, flatbuffers::DetachedBuffer&& buf, const TracingTraitsBase& traits) { LogTime(); *stream_ << id << ": " << TracingTraitsBase::SeverityString(traits.Severity()) << " " << traits.Name() << traits.TextFormat(buf) << endl; } void TextTracingRecorderImpl::BeginSpan(TracingSpanId id, TracingSpanId parent_id, absl::string_view name, absl::string_view text_format) { LogSpan(/* begin = */ true, id, parent_id, name, text_format); } void TextTracingRecorderImpl::EndSpan(TracingSpanId id, absl::string_view name, absl::string_view text_format) { LogSpan(/* begin = */ false, id, TracingSpanId(0), name, text_format); } void TextTracingRecorderImpl::LogSpan(bool begin, TracingSpanId id, TracingSpanId parent_id, absl::string_view name, absl::string_view text_format) { LogTime(); *stream_ << id << (begin ? ": BEGIN" : ": END"); if (name.length() > 0) { *stream_ << " " << name << " " << text_format; } if (begin && id != TracingSpanId(0)) { *stream_ << " parent: " << parent_id; } *stream_ << endl; } void TextTracingRecorderImpl::LogTime() { *stream_ << absl::FormatTime(absl::Now(), time_zone_) << " "; } TracingSpanImpl* TextTracingRecorderImpl::GetRootSpan() { return root_span_.get(); } std::unique_ptr TextTracingRecorderImpl::CreateChildSpan( TracingSpanId parent_span_id, flatbuffers::DetachedBuffer&& buf, const TracingTraitsBase& traits) { // NOTE: shared_from_this() is defined in a base class, so it returns // std::shared_ptr and we have to (safely) cast it here: auto shared_this = std::static_pointer_cast(shared_from_this()); return std::make_unique( shared_this, std::move(buf), traits, TracingSpanId::NextUniqueId(), parent_span_id); } TextTracingRecorderImpl::~TextTracingRecorderImpl() = default; } // namespace fcp::tracing_internal