xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/http2/core/http2_trace_logging.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Classes and utilities for supporting HTTP/2 trace logging, which logs
2 // information about all control and data frames sent and received over
3 // HTTP/2 connections.
4 
5 #ifndef QUICHE_HTTP2_CORE_HTTP2_TRACE_LOGGING_H_
6 #define QUICHE_HTTP2_CORE_HTTP2_TRACE_LOGGING_H_
7 
8 #include <cstdint>
9 
10 #include "absl/strings/string_view.h"
11 #include "quiche/common/platform/api/quiche_export.h"
12 #include "quiche/common/platform/api/quiche_logging.h"
13 #include "quiche/common/quiche_callbacks.h"
14 #include "quiche/spdy/core/http2_frame_decoder_adapter.h"
15 #include "quiche/spdy/core/recording_headers_handler.h"
16 #include "quiche/spdy/core/spdy_headers_handler_interface.h"
17 #include "quiche/spdy/core/spdy_protocol.h"
18 
19 // Logging macro to use for all HTTP/2 trace logging. Iff trace logging is
20 // enabled, logs at level INFO with a common prefix prepended (to facilitate
21 // post-hoc filtering of trace logging output).
22 #define HTTP2_TRACE_LOG(perspective, is_enabled) \
23   QUICHE_LOG_IF(INFO, is_enabled()) << "[HTTP2_TRACE " << perspective << "] "
24 
25 namespace http2 {
26 
27 // Intercepts deframing events to provide detailed logs. Intended to be used for
28 // manual debugging.
29 //
30 // Note any new methods in SpdyFramerVisitorInterface MUST be overridden here to
31 // properly forward the event. This could be ensured by making every event in
32 // SpdyFramerVisitorInterface a pure virtual.
33 class QUICHE_EXPORT Http2TraceLogger : public spdy::SpdyFramerVisitorInterface {
34  public:
35   typedef spdy::SpdyAltSvcWireFormat SpdyAltSvcWireFormat;
36   typedef spdy::SpdyErrorCode SpdyErrorCode;
37   typedef spdy::SpdyFramerVisitorInterface SpdyFramerVisitorInterface;
38   typedef spdy::SpdyPingId SpdyPingId;
39   typedef spdy::SpdyPriority SpdyPriority;
40   typedef spdy::SpdySettingsId SpdySettingsId;
41   typedef spdy::SpdyStreamId SpdyStreamId;
42 
43   Http2TraceLogger(SpdyFramerVisitorInterface* parent,
44                    absl::string_view perspective,
45                    quiche::MultiUseCallback<bool()> is_enabled,
46                    const void* connection_id);
47   ~Http2TraceLogger() override;
48 
49   Http2TraceLogger(const Http2TraceLogger&) = delete;
50   Http2TraceLogger& operator=(const Http2TraceLogger&) = delete;
51 
52   void OnError(http2::Http2DecoderAdapter::SpdyFramerError error,
53                std::string detailed_error) override;
54   void OnCommonHeader(SpdyStreamId stream_id, size_t length, uint8_t type,
55                       uint8_t flags) override;
56   spdy::SpdyHeadersHandlerInterface* OnHeaderFrameStart(
57       SpdyStreamId stream_id) override;
58   void OnHeaderFrameEnd(SpdyStreamId stream_id) override;
59   void OnDataFrameHeader(SpdyStreamId stream_id, size_t length,
60                          bool fin) override;
61   void OnStreamFrameData(SpdyStreamId stream_id, const char* data,
62                          size_t len) override;
63   void OnStreamEnd(SpdyStreamId stream_id) override;
64   void OnStreamPadLength(SpdyStreamId stream_id, size_t value) override;
65   void OnStreamPadding(SpdyStreamId stream_id, size_t len) override;
66   void OnRstStream(SpdyStreamId stream_id, SpdyErrorCode error_code) override;
67   void OnSetting(spdy::SpdySettingsId id, uint32_t value) override;
68   void OnPing(SpdyPingId unique_id, bool is_ack) override;
69   void OnSettings() override;
70   void OnSettingsEnd() override;
71   void OnSettingsAck() override;
72   void OnGoAway(SpdyStreamId last_accepted_stream_id,
73                 SpdyErrorCode error_code) override;
74   bool OnGoAwayFrameData(const char* goaway_data, size_t len) override;
75   void OnHeaders(SpdyStreamId stream_id, size_t payload_length,
76                  bool has_priority, int weight, SpdyStreamId parent_stream_id,
77                  bool exclusive, bool fin, bool end) override;
78   void OnWindowUpdate(SpdyStreamId stream_id, int delta_window_size) override;
79   void OnPushPromise(SpdyStreamId stream_id, SpdyStreamId promised_stream_id,
80                      bool end) override;
81   void OnContinuation(SpdyStreamId stream_id, size_t payload_length,
82                       bool end) override;
83   void OnAltSvc(SpdyStreamId stream_id, absl::string_view origin,
84                 const SpdyAltSvcWireFormat::AlternativeServiceVector&
85                     altsvc_vector) override;
86   void OnPriority(SpdyStreamId stream_id, SpdyStreamId parent_stream_id,
87                   int weight, bool exclusive) override;
88   void OnPriorityUpdate(SpdyStreamId prioritized_stream_id,
89                         absl::string_view priority_field_value) override;
90   bool OnUnknownFrame(SpdyStreamId stream_id, uint8_t frame_type) override;
91   void OnUnknownFrameStart(SpdyStreamId stream_id, size_t length, uint8_t type,
92                            uint8_t flags) override;
93   void OnUnknownFramePayload(SpdyStreamId stream_id,
94                              absl::string_view payload) override;
95 
96  private:
97   void LogReceivedHeaders() const;
98 
99   std::unique_ptr<spdy::RecordingHeadersHandler> recording_headers_handler_;
100 
101   SpdyFramerVisitorInterface* wrapped_;
102   const absl::string_view perspective_;
103   const quiche::MultiUseCallback<bool()> is_enabled_;
104   const void* connection_id_;
105 };
106 
107 // Visitor to log control frames that have been written.
108 class QUICHE_EXPORT Http2FrameLogger : public spdy::SpdyFrameVisitor {
109  public:
110   // This class will preface all of its log messages with the value of
111   // |connection_id| in hexadecimal.
Http2FrameLogger(absl::string_view perspective,quiche::MultiUseCallback<bool ()> is_enabled,const void * connection_id)112   Http2FrameLogger(absl::string_view perspective,
113                    quiche::MultiUseCallback<bool()> is_enabled,
114                    const void* connection_id)
115       : perspective_(perspective),
116         is_enabled_(std::move(is_enabled)),
117         connection_id_(connection_id) {}
118 
119   Http2FrameLogger(const Http2FrameLogger&) = delete;
120   Http2FrameLogger& operator=(const Http2FrameLogger&) = delete;
121 
122   void VisitRstStream(const spdy::SpdyRstStreamIR& rst_stream) override;
123   void VisitSettings(const spdy::SpdySettingsIR& settings) override;
124   void VisitPing(const spdy::SpdyPingIR& ping) override;
125   void VisitGoAway(const spdy::SpdyGoAwayIR& goaway) override;
126   void VisitHeaders(const spdy::SpdyHeadersIR& headers) override;
127   void VisitWindowUpdate(
128       const spdy::SpdyWindowUpdateIR& window_update) override;
129   void VisitPushPromise(const spdy::SpdyPushPromiseIR& push_promise) override;
130   void VisitContinuation(const spdy::SpdyContinuationIR& continuation) override;
131   void VisitAltSvc(const spdy::SpdyAltSvcIR& altsvc) override;
132   void VisitPriority(const spdy::SpdyPriorityIR& priority) override;
133   void VisitData(const spdy::SpdyDataIR& data) override;
134   void VisitPriorityUpdate(
135       const spdy::SpdyPriorityUpdateIR& priority_update) override;
136   void VisitAcceptCh(const spdy::SpdyAcceptChIR& accept_ch) override;
137   void VisitUnknown(const spdy::SpdyUnknownIR& ir) override;
138 
139  private:
140   const absl::string_view perspective_;
141   const quiche::MultiUseCallback<bool()> is_enabled_;
142   const void* connection_id_;
143 };
144 
145 }  // namespace http2
146 
147 #endif  // QUICHE_HTTP2_CORE_HTTP2_TRACE_LOGGING_H_
148