xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/http2/core/http2_trace_logging.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 #include "quiche/http2/core/http2_trace_logging.h"
2 
3 #include <cstdint>
4 #include <memory>
5 
6 #include "absl/strings/str_cat.h"
7 #include "absl/strings/string_view.h"
8 #include "quiche/common/platform/api/quiche_bug_tracker.h"
9 #include "quiche/common/platform/api/quiche_logging.h"
10 #include "quiche/common/quiche_callbacks.h"
11 #include "quiche/spdy/core/http2_header_block.h"
12 #include "quiche/spdy/core/spdy_protocol.h"
13 
14 // Convenience macros for printing function arguments in log lines in the
15 // format arg_name=value.
16 #define FORMAT_ARG(arg) " " #arg "=" << arg
17 #define FORMAT_INT_ARG(arg) " " #arg "=" << static_cast<int>(arg)
18 
19 // Convenience macros for printing Spdy*IR attributes in log lines in the
20 // format attrib_name=value.
21 #define FORMAT_ATTR(ir, attrib) " " #attrib "=" << ir.attrib()
22 #define FORMAT_INT_ATTR(ir, attrib) \
23   " " #attrib "=" << static_cast<int>(ir.attrib())
24 
25 namespace {
26 
27 // Logs a container, using a user-provided object to log each individual item.
28 template <typename T, typename ItemLogger>
29 struct ContainerLogger {
ContainerLogger__anon5472a3f60111::ContainerLogger30   explicit ContainerLogger(const T& c, ItemLogger l)
31       : container(c), item_logger(l) {}
32 
operator <<(std::ostream & out,const ContainerLogger & logger)33   friend std::ostream& operator<<(std::ostream& out,
34                                   const ContainerLogger& logger) {
35     out << "[";
36     auto begin = logger.container.begin();
37     for (auto it = begin; it != logger.container.end(); ++it) {
38       if (it != begin) {
39         out << ", ";
40       }
41       logger.item_logger.Log(out, *it);
42     }
43     out << "]";
44     return out;
45   }
46   const T& container;
47   ItemLogger item_logger;
48 };
49 
50 // Returns a ContainerLogger that will log |container| using |item_logger|.
51 template <typename T, typename ItemLogger>
LogContainer(const T & container,ItemLogger item_logger)52 auto LogContainer(const T& container, ItemLogger item_logger)
53     -> decltype(ContainerLogger<T, ItemLogger>(container, item_logger)) {
54   return ContainerLogger<T, ItemLogger>(container, item_logger);
55 }
56 
57 }  // anonymous namespace
58 
59 #define FORMAT_HEADER_BLOCK(ir) \
60   " header_block=" << LogContainer(ir.header_block(), LogHeaderBlockEntry())
61 
62 namespace http2 {
63 
64 using spdy::Http2HeaderBlock;
65 using spdy::SettingsMap;
66 using spdy::SpdyAltSvcIR;
67 using spdy::SpdyContinuationIR;
68 using spdy::SpdyDataIR;
69 using spdy::SpdyGoAwayIR;
70 using spdy::SpdyHeadersIR;
71 using spdy::SpdyPingIR;
72 using spdy::SpdyPriorityIR;
73 using spdy::SpdyPushPromiseIR;
74 using spdy::SpdyRstStreamIR;
75 using spdy::SpdySettingsIR;
76 using spdy::SpdyStreamId;
77 using spdy::SpdyUnknownIR;
78 using spdy::SpdyWindowUpdateIR;
79 
80 namespace {
81 
82 // Defines how elements of Http2HeaderBlocks are logged.
83 struct LogHeaderBlockEntry {
Loghttp2::__anon5472a3f60211::LogHeaderBlockEntry84   void Log(std::ostream& out,
85            const Http2HeaderBlock::value_type& entry) const {  // NOLINT
86     out << "\"" << entry.first << "\": \"" << entry.second << "\"";
87   }
88 };
89 
90 // Defines how elements of SettingsMap are logged.
91 struct LogSettingsEntry {
Loghttp2::__anon5472a3f60211::LogSettingsEntry92   void Log(std::ostream& out,
93            const SettingsMap::value_type& entry) const {  // NOLINT
94     out << spdy::SettingsIdToString(entry.first) << ": " << entry.second;
95   }
96 };
97 
98 // Defines how elements of AlternativeServiceVector are logged.
99 struct LogAlternativeService {
Loghttp2::__anon5472a3f60211::LogAlternativeService100   void Log(std::ostream& out,
101            const spdy::SpdyAltSvcWireFormat::AlternativeService& altsvc)
102       const {  // NOLINT
103     out << "{"
104         << "protocol_id=" << altsvc.protocol_id << " host=" << altsvc.host
105         << " port=" << altsvc.port
106         << " max_age_seconds=" << altsvc.max_age_seconds << " version=";
107     for (auto v : altsvc.version) {
108       out << v << ",";
109     }
110     out << "}";
111   }
112 };
113 
114 }  // anonymous namespace
115 
Http2TraceLogger(SpdyFramerVisitorInterface * parent,absl::string_view perspective,quiche::MultiUseCallback<bool ()> is_enabled,const void * connection_id)116 Http2TraceLogger::Http2TraceLogger(SpdyFramerVisitorInterface* parent,
117                                    absl::string_view perspective,
118                                    quiche::MultiUseCallback<bool()> is_enabled,
119                                    const void* connection_id)
120     : wrapped_(parent),
121       perspective_(perspective),
122       is_enabled_(std::move(is_enabled)),
123       connection_id_(connection_id) {}
124 
~Http2TraceLogger()125 Http2TraceLogger::~Http2TraceLogger() {
126   if (recording_headers_handler_ != nullptr &&
127       !recording_headers_handler_->decoded_block().empty()) {
128     HTTP2_TRACE_LOG(perspective_, is_enabled_)
129         << "connection_id=" << connection_id_
130         << " Received headers that were never logged! keys/values:"
131         << recording_headers_handler_->decoded_block().DebugString();
132   }
133 }
134 
OnError(Http2DecoderAdapter::SpdyFramerError error,std::string detailed_error)135 void Http2TraceLogger::OnError(Http2DecoderAdapter::SpdyFramerError error,
136                                std::string detailed_error) {
137   HTTP2_TRACE_LOG(perspective_, is_enabled_)
138       << "OnError:" << FORMAT_ARG(connection_id_)
139       << ", error=" << Http2DecoderAdapter::SpdyFramerErrorToString(error);
140   wrapped_->OnError(error, detailed_error);
141 }
142 
OnCommonHeader(SpdyStreamId stream_id,size_t length,uint8_t type,uint8_t flags)143 void Http2TraceLogger::OnCommonHeader(SpdyStreamId stream_id, size_t length,
144                                       uint8_t type, uint8_t flags) {
145   HTTP2_TRACE_LOG(perspective_, is_enabled_)
146       << "OnCommonHeader:" << FORMAT_ARG(connection_id_)
147       << FORMAT_ARG(stream_id) << FORMAT_ARG(length) << FORMAT_INT_ARG(type)
148       << FORMAT_INT_ARG(flags);
149   wrapped_->OnCommonHeader(stream_id, length, type, flags);
150 }
151 
OnDataFrameHeader(SpdyStreamId stream_id,size_t length,bool fin)152 void Http2TraceLogger::OnDataFrameHeader(SpdyStreamId stream_id, size_t length,
153                                          bool fin) {
154   HTTP2_TRACE_LOG(perspective_, is_enabled_)
155       << "OnDataFrameHeader:" << FORMAT_ARG(connection_id_)
156       << FORMAT_ARG(stream_id) << FORMAT_ARG(length) << FORMAT_ARG(fin);
157   wrapped_->OnDataFrameHeader(stream_id, length, fin);
158 }
159 
OnStreamFrameData(SpdyStreamId stream_id,const char * data,size_t len)160 void Http2TraceLogger::OnStreamFrameData(SpdyStreamId stream_id,
161                                          const char* data, size_t len) {
162   HTTP2_TRACE_LOG(perspective_, is_enabled_)
163       << "OnStreamFrameData:" << FORMAT_ARG(connection_id_)
164       << FORMAT_ARG(stream_id) << FORMAT_ARG(len);
165   wrapped_->OnStreamFrameData(stream_id, data, len);
166 }
167 
OnStreamEnd(SpdyStreamId stream_id)168 void Http2TraceLogger::OnStreamEnd(SpdyStreamId stream_id) {
169   HTTP2_TRACE_LOG(perspective_, is_enabled_)
170       << "OnStreamEnd:" << FORMAT_ARG(connection_id_) << FORMAT_ARG(stream_id);
171   wrapped_->OnStreamEnd(stream_id);
172 }
173 
OnStreamPadLength(SpdyStreamId stream_id,size_t value)174 void Http2TraceLogger::OnStreamPadLength(SpdyStreamId stream_id, size_t value) {
175   HTTP2_TRACE_LOG(perspective_, is_enabled_)
176       << "OnStreamPadLength:" << FORMAT_ARG(connection_id_)
177       << FORMAT_ARG(stream_id) << FORMAT_ARG(value);
178   wrapped_->OnStreamPadLength(stream_id, value);
179 }
180 
OnStreamPadding(SpdyStreamId stream_id,size_t len)181 void Http2TraceLogger::OnStreamPadding(SpdyStreamId stream_id, size_t len) {
182   HTTP2_TRACE_LOG(perspective_, is_enabled_)
183       << "OnStreamPadding:" << FORMAT_ARG(connection_id_)
184       << FORMAT_ARG(stream_id) << FORMAT_ARG(len);
185   wrapped_->OnStreamPadding(stream_id, len);
186 }
187 
OnHeaderFrameStart(SpdyStreamId stream_id)188 spdy::SpdyHeadersHandlerInterface* Http2TraceLogger::OnHeaderFrameStart(
189     SpdyStreamId stream_id) {
190   HTTP2_TRACE_LOG(perspective_, is_enabled_)
191       << "OnHeaderFrameStart:" << FORMAT_ARG(connection_id_)
192       << FORMAT_ARG(stream_id);
193   spdy::SpdyHeadersHandlerInterface* result =
194       wrapped_->OnHeaderFrameStart(stream_id);
195   if (is_enabled_()) {
196     recording_headers_handler_ =
197         std::make_unique<spdy::RecordingHeadersHandler>(result);
198     result = recording_headers_handler_.get();
199   } else {
200     recording_headers_handler_ = nullptr;
201   }
202   return result;
203 }
204 
OnHeaderFrameEnd(SpdyStreamId stream_id)205 void Http2TraceLogger::OnHeaderFrameEnd(SpdyStreamId stream_id) {
206   HTTP2_TRACE_LOG(perspective_, is_enabled_)
207       << "OnHeaderFrameEnd:" << FORMAT_ARG(connection_id_)
208       << FORMAT_ARG(stream_id);
209   LogReceivedHeaders();
210   wrapped_->OnHeaderFrameEnd(stream_id);
211   recording_headers_handler_ = nullptr;
212 }
213 
OnRstStream(SpdyStreamId stream_id,SpdyErrorCode error_code)214 void Http2TraceLogger::OnRstStream(SpdyStreamId stream_id,
215                                    SpdyErrorCode error_code) {
216   HTTP2_TRACE_LOG(perspective_, is_enabled_)
217       << "OnRstStream:" << FORMAT_ARG(connection_id_) << FORMAT_ARG(stream_id)
218       << " error_code=" << spdy::ErrorCodeToString(error_code);
219   wrapped_->OnRstStream(stream_id, error_code);
220 }
221 
OnSettings()222 void Http2TraceLogger::OnSettings() { wrapped_->OnSettings(); }
223 
OnSetting(SpdySettingsId id,uint32_t value)224 void Http2TraceLogger::OnSetting(SpdySettingsId id, uint32_t value) {
225   HTTP2_TRACE_LOG(perspective_, is_enabled_)
226       << "OnSetting:" << FORMAT_ARG(connection_id_)
227       << " id=" << spdy::SettingsIdToString(id) << FORMAT_ARG(value);
228   wrapped_->OnSetting(id, value);
229 }
230 
OnSettingsEnd()231 void Http2TraceLogger::OnSettingsEnd() {
232   HTTP2_TRACE_LOG(perspective_, is_enabled_)
233       << "OnSettingsEnd:" << FORMAT_ARG(connection_id_);
234   wrapped_->OnSettingsEnd();
235 }
236 
OnSettingsAck()237 void Http2TraceLogger::OnSettingsAck() {
238   HTTP2_TRACE_LOG(perspective_, is_enabled_)
239       << "OnSettingsAck:" << FORMAT_ARG(connection_id_);
240   wrapped_->OnSettingsAck();
241 }
242 
OnPing(SpdyPingId unique_id,bool is_ack)243 void Http2TraceLogger::OnPing(SpdyPingId unique_id, bool is_ack) {
244   HTTP2_TRACE_LOG(perspective_, is_enabled_)
245       << "OnPing:" << FORMAT_ARG(connection_id_) << FORMAT_ARG(unique_id)
246       << FORMAT_ARG(is_ack);
247   wrapped_->OnPing(unique_id, is_ack);
248 }
249 
OnGoAway(SpdyStreamId last_accepted_stream_id,SpdyErrorCode error_code)250 void Http2TraceLogger::OnGoAway(SpdyStreamId last_accepted_stream_id,
251                                 SpdyErrorCode error_code) {
252   HTTP2_TRACE_LOG(perspective_, is_enabled_)
253       << "OnGoAway:" << FORMAT_ARG(connection_id_)
254       << FORMAT_ARG(last_accepted_stream_id)
255       << " error_code=" << spdy::ErrorCodeToString(error_code);
256   wrapped_->OnGoAway(last_accepted_stream_id, error_code);
257 }
258 
OnGoAwayFrameData(const char * goaway_data,size_t len)259 bool Http2TraceLogger::OnGoAwayFrameData(const char* goaway_data, size_t len) {
260   return wrapped_->OnGoAwayFrameData(goaway_data, len);
261 }
262 
OnHeaders(SpdyStreamId stream_id,size_t payload_length,bool has_priority,int weight,SpdyStreamId parent_stream_id,bool exclusive,bool fin,bool end)263 void Http2TraceLogger::OnHeaders(SpdyStreamId stream_id, size_t payload_length,
264                                  bool has_priority, int weight,
265                                  SpdyStreamId parent_stream_id, bool exclusive,
266                                  bool fin, bool end) {
267   HTTP2_TRACE_LOG(perspective_, is_enabled_)
268       << "OnHeaders:" << FORMAT_ARG(connection_id_) << FORMAT_ARG(stream_id)
269       << FORMAT_ARG(payload_length) << FORMAT_ARG(has_priority)
270       << FORMAT_INT_ARG(weight) << FORMAT_ARG(parent_stream_id)
271       << FORMAT_ARG(exclusive) << FORMAT_ARG(fin) << FORMAT_ARG(end);
272   wrapped_->OnHeaders(stream_id, payload_length, has_priority, weight,
273                       parent_stream_id, exclusive, fin, end);
274 }
275 
OnWindowUpdate(SpdyStreamId stream_id,int delta_window_size)276 void Http2TraceLogger::OnWindowUpdate(SpdyStreamId stream_id,
277                                       int delta_window_size) {
278   HTTP2_TRACE_LOG(perspective_, is_enabled_)
279       << "OnWindowUpdate:" << FORMAT_ARG(connection_id_)
280       << FORMAT_ARG(stream_id) << FORMAT_ARG(delta_window_size);
281   wrapped_->OnWindowUpdate(stream_id, delta_window_size);
282 }
283 
OnPushPromise(SpdyStreamId original_stream_id,SpdyStreamId promised_stream_id,bool end)284 void Http2TraceLogger::OnPushPromise(SpdyStreamId original_stream_id,
285                                      SpdyStreamId promised_stream_id,
286                                      bool end) {
287   HTTP2_TRACE_LOG(perspective_, is_enabled_)
288       << "OnPushPromise:" << FORMAT_ARG(connection_id_)
289       << FORMAT_ARG(original_stream_id) << FORMAT_ARG(promised_stream_id)
290       << FORMAT_ARG(end);
291   wrapped_->OnPushPromise(original_stream_id, promised_stream_id, end);
292 }
293 
OnContinuation(SpdyStreamId stream_id,size_t payload_length,bool end)294 void Http2TraceLogger::OnContinuation(SpdyStreamId stream_id,
295                                       size_t payload_length, bool end) {
296   HTTP2_TRACE_LOG(perspective_, is_enabled_)
297       << "OnContinuation:" << FORMAT_ARG(connection_id_)
298       << FORMAT_ARG(stream_id) << FORMAT_ARG(payload_length) << FORMAT_ARG(end);
299   wrapped_->OnContinuation(stream_id, payload_length, end);
300 }
301 
OnAltSvc(SpdyStreamId stream_id,absl::string_view origin,const SpdyAltSvcWireFormat::AlternativeServiceVector & altsvc_vector)302 void Http2TraceLogger::OnAltSvc(
303     SpdyStreamId stream_id, absl::string_view origin,
304     const SpdyAltSvcWireFormat::AlternativeServiceVector& altsvc_vector) {
305   HTTP2_TRACE_LOG(perspective_, is_enabled_)
306       << "OnAltSvc:" << FORMAT_ARG(connection_id_) << FORMAT_ARG(stream_id)
307       << FORMAT_ARG(origin) << " altsvc_vector="
308       << LogContainer(altsvc_vector, LogAlternativeService());
309   wrapped_->OnAltSvc(stream_id, origin, altsvc_vector);
310 }
311 
OnPriority(SpdyStreamId stream_id,SpdyStreamId parent_stream_id,int weight,bool exclusive)312 void Http2TraceLogger::OnPriority(SpdyStreamId stream_id,
313                                   SpdyStreamId parent_stream_id, int weight,
314                                   bool exclusive) {
315   HTTP2_TRACE_LOG(perspective_, is_enabled_)
316       << "OnPriority:" << FORMAT_ARG(connection_id_) << FORMAT_ARG(stream_id)
317       << FORMAT_ARG(parent_stream_id) << FORMAT_INT_ARG(weight)
318       << FORMAT_ARG(exclusive);
319   wrapped_->OnPriority(stream_id, parent_stream_id, weight, exclusive);
320 }
321 
OnPriorityUpdate(SpdyStreamId prioritized_stream_id,absl::string_view priority_field_value)322 void Http2TraceLogger::OnPriorityUpdate(
323     SpdyStreamId prioritized_stream_id,
324     absl::string_view priority_field_value) {
325   HTTP2_TRACE_LOG(perspective_, is_enabled_)
326       << "OnPriorityUpdate:" << FORMAT_ARG(connection_id_)
327       << FORMAT_ARG(prioritized_stream_id) << FORMAT_ARG(priority_field_value);
328   wrapped_->OnPriorityUpdate(prioritized_stream_id, priority_field_value);
329 }
330 
OnUnknownFrame(SpdyStreamId stream_id,uint8_t frame_type)331 bool Http2TraceLogger::OnUnknownFrame(SpdyStreamId stream_id,
332                                       uint8_t frame_type) {
333   HTTP2_TRACE_LOG(perspective_, is_enabled_)
334       << "OnUnknownFrame:" << FORMAT_ARG(connection_id_)
335       << FORMAT_ARG(stream_id) << FORMAT_INT_ARG(frame_type);
336   return wrapped_->OnUnknownFrame(stream_id, frame_type);
337 }
338 
OnUnknownFrameStart(spdy::SpdyStreamId stream_id,size_t length,uint8_t type,uint8_t flags)339 void Http2TraceLogger::OnUnknownFrameStart(spdy::SpdyStreamId stream_id,
340                                            size_t length, uint8_t type,
341                                            uint8_t flags) {
342   HTTP2_TRACE_LOG(perspective_, is_enabled_)
343       << "OnUnknownFrameStart:" << FORMAT_ARG(connection_id_)
344       << FORMAT_ARG(stream_id) << FORMAT_ARG(length) << FORMAT_INT_ARG(type)
345       << FORMAT_INT_ARG(flags);
346   wrapped_->OnUnknownFrameStart(stream_id, length, type, flags);
347 }
348 
OnUnknownFramePayload(spdy::SpdyStreamId stream_id,absl::string_view payload)349 void Http2TraceLogger::OnUnknownFramePayload(spdy::SpdyStreamId stream_id,
350                                              absl::string_view payload) {
351   HTTP2_TRACE_LOG(perspective_, is_enabled_)
352       << "OnUnknownFramePayload:" << FORMAT_ARG(connection_id_)
353       << FORMAT_ARG(stream_id) << " length=" << payload.size();
354   wrapped_->OnUnknownFramePayload(stream_id, payload);
355 }
356 
LogReceivedHeaders() const357 void Http2TraceLogger::LogReceivedHeaders() const {
358   if (recording_headers_handler_ == nullptr) {
359     // Trace logging was not enabled when the start of the header block was
360     // received.
361     return;
362   }
363   HTTP2_TRACE_LOG(perspective_, is_enabled_)
364       << "Received headers;" << FORMAT_ARG(connection_id_) << " keys/values:"
365       << recording_headers_handler_->decoded_block().DebugString()
366       << " compressed_bytes="
367       << recording_headers_handler_->compressed_header_bytes()
368       << " uncompressed_bytes="
369       << recording_headers_handler_->uncompressed_header_bytes();
370 }
371 
VisitRstStream(const SpdyRstStreamIR & rst_stream)372 void Http2FrameLogger::VisitRstStream(const SpdyRstStreamIR& rst_stream) {
373   HTTP2_TRACE_LOG(perspective_, is_enabled_)
374       << "Wrote SpdyRstStreamIR:" << FORMAT_ARG(connection_id_)
375       << FORMAT_ATTR(rst_stream, stream_id)
376       << " error_code=" << spdy::ErrorCodeToString(rst_stream.error_code());
377 }
378 
VisitSettings(const SpdySettingsIR & settings)379 void Http2FrameLogger::VisitSettings(const SpdySettingsIR& settings) {
380   HTTP2_TRACE_LOG(perspective_, is_enabled_)
381       << "Wrote SpdySettingsIR:" << FORMAT_ARG(connection_id_)
382       << FORMAT_ATTR(settings, is_ack)
383       << " values=" << LogContainer(settings.values(), LogSettingsEntry());
384 }
385 
VisitPing(const SpdyPingIR & ping)386 void Http2FrameLogger::VisitPing(const SpdyPingIR& ping) {
387   HTTP2_TRACE_LOG(perspective_, is_enabled_)
388       << "Wrote SpdyPingIR:" << FORMAT_ARG(connection_id_)
389       << FORMAT_ATTR(ping, id) << FORMAT_ATTR(ping, is_ack);
390 }
391 
VisitGoAway(const SpdyGoAwayIR & goaway)392 void Http2FrameLogger::VisitGoAway(const SpdyGoAwayIR& goaway) {
393   HTTP2_TRACE_LOG(perspective_, is_enabled_)
394       << "Wrote SpdyGoAwayIR:" << FORMAT_ARG(connection_id_)
395       << FORMAT_ATTR(goaway, last_good_stream_id)
396       << " error_code=" << spdy::ErrorCodeToString(goaway.error_code())
397       << FORMAT_ATTR(goaway, description);
398 }
399 
VisitHeaders(const SpdyHeadersIR & headers)400 void Http2FrameLogger::VisitHeaders(const SpdyHeadersIR& headers) {
401   HTTP2_TRACE_LOG(perspective_, is_enabled_)
402       << "Wrote SpdyHeadersIR:" << FORMAT_ARG(connection_id_)
403       << FORMAT_ATTR(headers, stream_id) << FORMAT_ATTR(headers, fin)
404       << FORMAT_ATTR(headers, has_priority) << FORMAT_INT_ATTR(headers, weight)
405       << FORMAT_ATTR(headers, parent_stream_id)
406       << FORMAT_ATTR(headers, exclusive) << FORMAT_ATTR(headers, padded)
407       << FORMAT_ATTR(headers, padding_payload_len)
408       << FORMAT_HEADER_BLOCK(headers);
409 }
410 
VisitWindowUpdate(const SpdyWindowUpdateIR & window_update)411 void Http2FrameLogger::VisitWindowUpdate(
412     const SpdyWindowUpdateIR& window_update) {
413   HTTP2_TRACE_LOG(perspective_, is_enabled_)
414       << "Wrote SpdyWindowUpdateIR:" << FORMAT_ARG(connection_id_)
415       << FORMAT_ATTR(window_update, stream_id)
416       << FORMAT_ATTR(window_update, delta);
417 }
418 
VisitPushPromise(const SpdyPushPromiseIR & push_promise)419 void Http2FrameLogger::VisitPushPromise(const SpdyPushPromiseIR& push_promise) {
420   HTTP2_TRACE_LOG(perspective_, is_enabled_)
421       << "Wrote SpdyPushPromiseIR:" << FORMAT_ARG(connection_id_)
422       << FORMAT_ATTR(push_promise, stream_id) << FORMAT_ATTR(push_promise, fin)
423       << FORMAT_ATTR(push_promise, promised_stream_id)
424       << FORMAT_ATTR(push_promise, padded)
425       << FORMAT_ATTR(push_promise, padding_payload_len)
426       << FORMAT_HEADER_BLOCK(push_promise);
427 }
428 
VisitContinuation(const SpdyContinuationIR & continuation)429 void Http2FrameLogger::VisitContinuation(
430     const SpdyContinuationIR& continuation) {
431   HTTP2_TRACE_LOG(perspective_, is_enabled_)
432       << "Wrote SpdyContinuationIR:" << FORMAT_ARG(connection_id_)
433       << FORMAT_ATTR(continuation, stream_id)
434       << FORMAT_ATTR(continuation, end_headers);
435 }
436 
VisitAltSvc(const SpdyAltSvcIR & altsvc)437 void Http2FrameLogger::VisitAltSvc(const SpdyAltSvcIR& altsvc) {
438   HTTP2_TRACE_LOG(perspective_, is_enabled_)
439       << "Wrote SpdyAltSvcIR:" << FORMAT_ARG(connection_id_)
440       << FORMAT_ATTR(altsvc, stream_id) << FORMAT_ATTR(altsvc, origin)
441       << " altsvc_vector="
442       << LogContainer(altsvc.altsvc_vector(), LogAlternativeService());
443 }
444 
VisitPriority(const SpdyPriorityIR & priority)445 void Http2FrameLogger::VisitPriority(const SpdyPriorityIR& priority) {
446   HTTP2_TRACE_LOG(perspective_, is_enabled_)
447       << "Wrote SpdyPriorityIR:" << FORMAT_ARG(connection_id_)
448       << FORMAT_ATTR(priority, stream_id)
449       << FORMAT_ATTR(priority, parent_stream_id)
450       << FORMAT_INT_ATTR(priority, weight) << FORMAT_ATTR(priority, exclusive);
451 }
452 
VisitData(const SpdyDataIR & data)453 void Http2FrameLogger::VisitData(const SpdyDataIR& data) {
454   HTTP2_TRACE_LOG(perspective_, is_enabled_)
455       << "Wrote SpdyDataIR:" << FORMAT_ARG(connection_id_)
456       << FORMAT_ATTR(data, stream_id) << FORMAT_ATTR(data, fin)
457       << " data_len=" << data.data_len() << FORMAT_ATTR(data, padded)
458       << FORMAT_ATTR(data, padding_payload_len);
459 }
460 
VisitPriorityUpdate(const spdy::SpdyPriorityUpdateIR & priority_update)461 void Http2FrameLogger::VisitPriorityUpdate(
462     const spdy::SpdyPriorityUpdateIR& priority_update) {
463   HTTP2_TRACE_LOG(perspective_, is_enabled_)
464       << "Wrote SpdyPriorityUpdateIR:" << FORMAT_ARG(connection_id_)
465       << FORMAT_ATTR(priority_update, stream_id)
466       << FORMAT_ATTR(priority_update, prioritized_stream_id)
467       << FORMAT_ATTR(priority_update, priority_field_value);
468 }
469 
VisitAcceptCh(const spdy::SpdyAcceptChIR &)470 void Http2FrameLogger::VisitAcceptCh(
471     const spdy::SpdyAcceptChIR& /*accept_ch*/) {
472   QUICHE_BUG(bug_2794_2)
473       << "Sending ACCEPT_CH frames is currently unimplemented.";
474 }
475 
VisitUnknown(const SpdyUnknownIR & ir)476 void Http2FrameLogger::VisitUnknown(const SpdyUnknownIR& ir) {
477   HTTP2_TRACE_LOG(perspective_, is_enabled_)
478       << "Wrote SpdyUnknownIR:" << FORMAT_ARG(connection_id_)
479       << FORMAT_ATTR(ir, stream_id) << FORMAT_INT_ATTR(ir, type)
480       << FORMAT_INT_ATTR(ir, flags) << FORMAT_ATTR(ir, length);
481 }
482 
483 }  // namespace http2
484