1 /*
2  * Copyright (c) Facebook, Inc. and its affiliates.
3  *
4  * This source code is licensed under the MIT license found in the
5  * LICENSE file in the root directory of this source tree.
6  *
7  */
8 #include <quic/logging/QLoggerTypes.h>
9 
10 #include <quic/QuicException.h>
11 #include <quic/logging/QLoggerConstants.h>
12 
13 namespace quic {
14 
toDynamic() const15 folly::dynamic PaddingFrameLog::toDynamic() const {
16   folly::dynamic d = folly::dynamic::object();
17   d["frame_type"] = toQlogString(FrameType::PADDING);
18   d["num_frames"] = numFrames;
19   return d;
20 }
21 
toDynamic() const22 folly::dynamic RstStreamFrameLog::toDynamic() const {
23   folly::dynamic d = folly::dynamic::object();
24   d["frame_type"] = toQlogString(FrameType::RST_STREAM);
25   d["stream_id"] = streamId;
26   d["error_code"] = errorCode;
27   d["offset"] = offset;
28   return d;
29 }
30 
toDynamic() const31 folly::dynamic ConnectionCloseFrameLog::toDynamic() const {
32   folly::dynamic d = folly::dynamic::object();
33 
34   auto isTransportErrorCode = errorCode.asTransportErrorCode();
35   auto isApplicationErrorCode = errorCode.asApplicationErrorCode();
36   auto isLocalErrorCode = errorCode.asLocalErrorCode();
37 
38   if (isTransportErrorCode || isLocalErrorCode) {
39     d["frame_type"] = toQlogString(FrameType::CONNECTION_CLOSE);
40   } else if (isApplicationErrorCode) {
41     d["frame_type"] = toQlogString(FrameType::CONNECTION_CLOSE_APP_ERR);
42   }
43 
44   d["error_code"] = toString(errorCode);
45   d["reason_phrase"] = reasonPhrase;
46   d["closing_frame_type"] = toString(closingFrameType);
47   return d;
48 }
49 
toDynamic() const50 folly::dynamic MaxDataFrameLog::toDynamic() const {
51   folly::dynamic d = folly::dynamic::object();
52   d["frame_type"] = toQlogString(FrameType::MAX_DATA);
53   d["maximum_data"] = maximumData;
54   return d;
55 }
56 
toDynamic() const57 folly::dynamic MaxStreamDataFrameLog::toDynamic() const {
58   folly::dynamic d = folly::dynamic::object();
59   d["frame_type"] = toQlogString(FrameType::MAX_STREAM_DATA);
60   d["stream_id"] = streamId;
61   d["maximum_data"] = maximumData;
62   return d;
63 }
64 
toDynamic() const65 folly::dynamic MaxStreamsFrameLog::toDynamic() const {
66   folly::dynamic d = folly::dynamic::object();
67   FrameType type;
68   if (isForBidirectional) {
69     type = FrameType::MAX_STREAMS_BIDI;
70   } else {
71     type = FrameType::MAX_STREAMS_UNI;
72   }
73   d["frame_type"] = toString(type);
74   d["max_streams"] = maxStreams;
75   return d;
76 }
77 
toDynamic() const78 folly::dynamic StreamsBlockedFrameLog::toDynamic() const {
79   folly::dynamic d = folly::dynamic::object();
80   FrameType type;
81   if (isForBidirectional) {
82     type = FrameType::STREAMS_BLOCKED_BIDI;
83   } else {
84     type = FrameType::STREAMS_BLOCKED_UNI;
85   }
86   d["frame_type"] = toString(type);
87   d["stream_limit"] = streamLimit;
88   return d;
89 }
90 
toDynamic() const91 folly::dynamic PingFrameLog::toDynamic() const {
92   folly::dynamic d = folly::dynamic::object();
93   d["frame_type"] = toQlogString(FrameType::PING);
94   return d;
95 }
96 
toDynamic() const97 folly::dynamic DataBlockedFrameLog::toDynamic() const {
98   folly::dynamic d = folly::dynamic::object();
99   d["frame_type"] = toQlogString(FrameType::DATA_BLOCKED);
100   d["data_limit"] = dataLimit;
101   return d;
102 }
103 
toDynamic() const104 folly::dynamic KnobFrameLog::toDynamic() const {
105   folly::dynamic d = folly::dynamic::object();
106   d["frame_type"] = toQlogString(FrameType::KNOB);
107   d["knob_space"] = knobSpace;
108   d["knob_id"] = knobId;
109   d["knob_blob_len"] = knobBlobLen;
110   return d;
111 }
112 
toDynamic() const113 folly::dynamic AckFrequencyFrameLog::toDynamic() const {
114   folly::dynamic d = folly::dynamic::object();
115   d["frame_type"] = toQlogString(FrameType::ACK_FREQUENCY);
116   d["sequence_number"] = sequenceNumber;
117   d["packet_tolerance"] = packetTolerance;
118   d["update_max_ack_delay"] = updateMaxAckDelay;
119   d["ignore_order"] = ignoreOrder;
120   return d;
121 }
122 
toDynamic() const123 folly::dynamic StreamDataBlockedFrameLog::toDynamic() const {
124   folly::dynamic d = folly::dynamic::object();
125   d["frame_type"] = toQlogString(FrameType::STREAM_DATA_BLOCKED);
126   d["stream_id"] = streamId;
127   d["data_limit"] = dataLimit;
128   return d;
129 }
130 
toDynamic() const131 folly::dynamic StreamFrameLog::toDynamic() const {
132   folly::dynamic d = folly::dynamic::object();
133   d["offset"] = offset;
134   d["length"] = len;
135   d["fin"] = fin;
136   d["stream_id"] = folly::to<std::string>(streamId);
137   d["frame_type"] = toQlogString(FrameType::STREAM);
138   return d;
139 }
140 
toDynamic() const141 folly::dynamic CryptoFrameLog::toDynamic() const {
142   folly::dynamic d = folly::dynamic::object();
143   d["frame_type"] = toQlogString(FrameType::CRYPTO_FRAME);
144   d["offset"] = offset;
145   d["len"] = len;
146   return d;
147 }
148 
toDynamic() const149 folly::dynamic StopSendingFrameLog::toDynamic() const {
150   folly::dynamic d = folly::dynamic::object();
151   d["frame_type"] = toQlogString(FrameType::STOP_SENDING);
152   d["stream_id"] = streamId;
153   d["error_code"] = errorCode;
154   return d;
155 }
156 
toDynamic() const157 folly::dynamic PathChallengeFrameLog::toDynamic() const {
158   folly::dynamic d = folly::dynamic::object();
159   d["frame_type"] = toQlogString(FrameType::PATH_CHALLENGE);
160   d["path_data"] = pathData;
161   return d;
162 }
163 
toDynamic() const164 folly::dynamic PathResponseFrameLog::toDynamic() const {
165   folly::dynamic d = folly::dynamic::object();
166   d["frame_type"] = toQlogString(FrameType::PATH_RESPONSE);
167   d["path_data"] = pathData;
168   return d;
169 }
170 
toDynamic() const171 folly::dynamic NewConnectionIdFrameLog::toDynamic() const {
172   folly::dynamic d = folly::dynamic::object();
173   d["frame_type"] = toQlogString(FrameType::NEW_CONNECTION_ID);
174   d["sequence"] = sequence;
175 
176   folly::dynamic dToken = folly::dynamic::array();
177   for (const auto& a : token) {
178     dToken.push_back(a);
179   }
180 
181   d["token"] = dToken;
182   return d;
183 }
184 
toDynamic() const185 folly::dynamic RetireConnectionIdFrameLog::toDynamic() const {
186   folly::dynamic d = folly::dynamic::object();
187   d["frame_type"] = toQlogString(FrameType::RETIRE_CONNECTION_ID);
188   d["sequence"] = sequence;
189   return d;
190 }
191 
toDynamic() const192 folly::dynamic ReadAckFrameLog::toDynamic() const {
193   folly::dynamic d = folly::dynamic::object();
194   folly::dynamic ackRangeDynamic = folly::dynamic::array();
195 
196   for (const auto& b : ackBlocks) {
197     ackRangeDynamic.push_back(
198         folly::dynamic::array(b.startPacket, b.endPacket));
199   }
200   d["acked_ranges"] = ackRangeDynamic;
201   d["frame_type"] = toQlogString(FrameType::ACK);
202   d["ack_delay"] = ackDelay.count();
203   return d;
204 }
205 
toDynamic() const206 folly::dynamic WriteAckFrameLog::toDynamic() const {
207   folly::dynamic d = folly::dynamic::object();
208   folly::dynamic ackRangeDynamic = folly::dynamic::array();
209 
210   for (auto it = ackBlocks.cbegin(); it != ackBlocks.cend(); ++it) {
211     ackRangeDynamic.push_back(folly::dynamic::array(it->start, it->end));
212   }
213   d["acked_ranges"] = ackRangeDynamic;
214   d["frame_type"] = toQlogString(FrameType::ACK);
215   d["ack_delay"] = ackDelay.count();
216   return d;
217 }
218 
toDynamic() const219 folly::dynamic ReadNewTokenFrameLog::toDynamic() const {
220   folly::dynamic d = folly::dynamic::object();
221   d["frame_type"] = toQlogString(FrameType::NEW_TOKEN);
222   return d;
223 }
224 
toDynamic() const225 folly::dynamic HandshakeDoneFrameLog::toDynamic() const {
226   folly::dynamic d = folly::dynamic::object();
227   d["frame_type"] = toQlogString(FrameType::HANDSHAKE_DONE);
228   return d;
229 }
230 
toDynamic() const231 folly::dynamic VersionNegotiationLog::toDynamic() const {
232   folly::dynamic d = folly::dynamic::object();
233   d = folly::dynamic::array();
234   for (const auto& v : versions) {
235     d.push_back(toString(v));
236   }
237   return d;
238 }
239 
toDynamic() const240 folly::dynamic QLogPacketEvent::toDynamic() const {
241   // creating a folly::dynamic array to hold the information corresponding to
242   // the event fields relative_time, category, event_type, trigger, data
243   folly::dynamic d = folly::dynamic::array(
244       folly::to<std::string>(refTime.count()),
245       "transport",
246       toString(eventType));
247   folly::dynamic data = folly::dynamic::object();
248 
249   data["header"] = folly::dynamic::object("packet_size", packetSize);
250 
251   // A Retry packet does not include a packet number.
252   if (packetType != toString(LongHeader::Types::Retry)) {
253     data["header"]["packet_number"] = packetNum;
254     data["frames"] = folly::dynamic::array();
255 
256     for (const auto& frame : frames) {
257       data["frames"].push_back(frame->toDynamic());
258     }
259   }
260   data["packet_type"] = packetType;
261 
262   d.push_back(std::move(data));
263   return d;
264 }
265 
toDynamic() const266 folly::dynamic QLogVersionNegotiationEvent::toDynamic() const {
267   // creating a folly::dynamic array to hold the information corresponding to
268   // the event fields relative_time, category, event_type, trigger, data
269 
270   folly::dynamic d = folly::dynamic::array(
271       folly::to<std::string>(refTime.count()),
272       "transport",
273       toString(eventType));
274   folly::dynamic data = folly::dynamic::object();
275 
276   data["versions"] = versionLog->toDynamic();
277   data["header"] = folly::dynamic::object("packet_size", packetSize);
278   data["packet_type"] = packetType;
279 
280   d.push_back(std::move(data));
281   return d;
282 }
283 
toDynamic() const284 folly::dynamic QLogRetryEvent::toDynamic() const {
285   folly::dynamic d = folly::dynamic::array(
286       folly::to<std::string>(refTime.count()),
287       "transport",
288       toString(eventType));
289   folly::dynamic data = folly::dynamic::object();
290 
291   data["header"] = folly::dynamic::object("packet_size", packetSize);
292   data["packet_type"] = packetType;
293   data["token_size"] = tokenSize;
294 
295   d.push_back(std::move(data));
296   return d;
297 }
298 
QLogConnectionCloseEvent(std::string errorIn,std::string reasonIn,bool drainConnectionIn,bool sendCloseImmediatelyIn,std::chrono::microseconds refTimeIn)299 QLogConnectionCloseEvent::QLogConnectionCloseEvent(
300     std::string errorIn,
301     std::string reasonIn,
302     bool drainConnectionIn,
303     bool sendCloseImmediatelyIn,
304     std::chrono::microseconds refTimeIn)
305     : error{std::move(errorIn)},
306       reason{std::move(reasonIn)},
307       drainConnection{drainConnectionIn},
308       sendCloseImmediately{sendCloseImmediatelyIn} {
309   eventType = QLogEventType::ConnectionClose;
310   refTime = refTimeIn;
311 }
312 
toDynamic() const313 folly::dynamic QLogConnectionCloseEvent::toDynamic() const {
314   // creating a folly::dynamic array to hold the information corresponding to
315   // the event fields relative_time, category, event_type, trigger, data
316   folly::dynamic d = folly::dynamic::array(
317       folly::to<std::string>(refTime.count()),
318       "connectivity",
319       toString(eventType));
320   folly::dynamic data = folly::dynamic::object();
321 
322   data["error"] = error;
323   data["reason"] = reason;
324   data["drain_connection"] = drainConnection;
325   data["send_close_immediately"] = sendCloseImmediately;
326 
327   d.push_back(std::move(data));
328   return d;
329 }
330 
QLogTransportSummaryEvent(uint64_t totalBytesSentIn,uint64_t totalBytesRecvdIn,uint64_t sumCurWriteOffsetIn,uint64_t sumMaxObservedOffsetIn,uint64_t sumCurStreamBufferLenIn,uint64_t totalBytesRetransmittedIn,uint64_t totalStreamBytesClonedIn,uint64_t totalBytesClonedIn,uint64_t totalCryptoDataWrittenIn,uint64_t totalCryptoDataRecvdIn,uint64_t currentWritableBytesIn,uint64_t currentConnFlowControlIn,bool usedZeroRttIn,QuicVersion quicVersionIn,uint64_t dsrPacketCountIn,std::chrono::microseconds refTimeIn)331 QLogTransportSummaryEvent::QLogTransportSummaryEvent(
332     uint64_t totalBytesSentIn,
333     uint64_t totalBytesRecvdIn,
334     uint64_t sumCurWriteOffsetIn,
335     uint64_t sumMaxObservedOffsetIn,
336     uint64_t sumCurStreamBufferLenIn,
337     uint64_t totalBytesRetransmittedIn,
338     uint64_t totalStreamBytesClonedIn,
339     uint64_t totalBytesClonedIn,
340     uint64_t totalCryptoDataWrittenIn,
341     uint64_t totalCryptoDataRecvdIn,
342     uint64_t currentWritableBytesIn,
343     uint64_t currentConnFlowControlIn,
344     bool usedZeroRttIn,
345     QuicVersion quicVersionIn,
346     uint64_t dsrPacketCountIn,
347     std::chrono::microseconds refTimeIn)
348     : totalBytesSent{totalBytesSentIn},
349       totalBytesRecvd{totalBytesRecvdIn},
350       sumCurWriteOffset{sumCurWriteOffsetIn},
351       sumMaxObservedOffset{sumMaxObservedOffsetIn},
352       sumCurStreamBufferLen{sumCurStreamBufferLenIn},
353       totalBytesRetransmitted{totalBytesRetransmittedIn},
354       totalStreamBytesCloned{totalStreamBytesClonedIn},
355       totalBytesCloned{totalBytesClonedIn},
356       totalCryptoDataWritten{totalCryptoDataWrittenIn},
357       totalCryptoDataRecvd{totalCryptoDataRecvdIn},
358       currentWritableBytes{currentWritableBytesIn},
359       currentConnFlowControl{currentConnFlowControlIn},
360       usedZeroRtt{usedZeroRttIn},
361       quicVersion{quicVersionIn},
362       dsrPacketCount{dsrPacketCountIn} {
363   eventType = QLogEventType::TransportSummary;
364   refTime = refTimeIn;
365 }
366 
toDynamic() const367 folly::dynamic QLogTransportSummaryEvent::toDynamic() const {
368   // creating a folly::dynamic array to hold the information corresponding to
369   // the event fields relative_time, category, event_type, trigger, data
370   folly::dynamic d = folly::dynamic::array(
371       folly::to<std::string>(refTime.count()),
372       "transport",
373       toString(eventType));
374   folly::dynamic data = folly::dynamic::object();
375 
376   data["total_bytes_sent"] = totalBytesSent;
377   data["total_bytes_recvd"] = totalBytesRecvd;
378   data["sum_cur_write_offset"] = sumCurWriteOffset;
379   data["sum_max_observed_offset"] = sumMaxObservedOffset;
380   data["sum_cur_stream_buffer_len"] = sumCurStreamBufferLen;
381   data["total_bytes_retransmitted"] = totalBytesRetransmitted;
382   data["total_stream_bytes_cloned"] = totalStreamBytesCloned;
383   data["total_bytes_cloned"] = totalBytesCloned;
384   data["total_crypto_data_written"] = totalCryptoDataWritten;
385   data["total_crypto_data_recvd"] = totalCryptoDataRecvd;
386   data["current_writable_bytes"] = currentWritableBytes;
387   data["current_conn_flow_control"] = currentConnFlowControl;
388   data["used_zero_rtt"] = usedZeroRtt;
389   data["quic_version"] =
390       static_cast<std::underlying_type<decltype(quicVersion)>::type>(
391           quicVersion);
392   data["dsr_packet_count"] = dsrPacketCount;
393 
394   d.push_back(std::move(data));
395   return d;
396 }
397 
QLogCongestionMetricUpdateEvent(uint64_t bytesInFlightIn,uint64_t currentCwndIn,std::string congestionEventIn,std::string stateIn,std::string recoveryStateIn,std::chrono::microseconds refTimeIn)398 QLogCongestionMetricUpdateEvent::QLogCongestionMetricUpdateEvent(
399     uint64_t bytesInFlightIn,
400     uint64_t currentCwndIn,
401     std::string congestionEventIn,
402     std::string stateIn,
403     std::string recoveryStateIn,
404     std::chrono::microseconds refTimeIn)
405     : bytesInFlight{bytesInFlightIn},
406       currentCwnd{currentCwndIn},
407       congestionEvent{std::move(congestionEventIn)},
408       state{std::move(stateIn)},
409       recoveryState{std::move(recoveryStateIn)} {
410   eventType = QLogEventType::CongestionMetricUpdate;
411   refTime = refTimeIn;
412 }
413 
toDynamic() const414 folly::dynamic QLogCongestionMetricUpdateEvent::toDynamic() const {
415   // creating a folly::dynamic array to hold the information corresponding to
416   // the event fields relative_time, category, event_type, trigger, data
417   folly::dynamic d = folly::dynamic::array(
418       folly::to<std::string>(refTime.count()),
419       "metric_update",
420       toString(eventType));
421   folly::dynamic data = folly::dynamic::object();
422 
423   data["bytes_in_flight"] = bytesInFlight;
424   data["current_cwnd"] = currentCwnd;
425   data["congestion_event"] = congestionEvent;
426   data["state"] = state;
427   data["recovery_state"] = recoveryState;
428 
429   d.push_back(std::move(data));
430   return d;
431 }
432 
QLogAppLimitedUpdateEvent(bool limitedIn,std::chrono::microseconds refTimeIn)433 QLogAppLimitedUpdateEvent::QLogAppLimitedUpdateEvent(
434     bool limitedIn,
435     std::chrono::microseconds refTimeIn)
436     : limited(limitedIn) {
437   eventType = QLogEventType::AppLimitedUpdate;
438   refTime = refTimeIn;
439 }
440 
toDynamic() const441 folly::dynamic QLogAppLimitedUpdateEvent::toDynamic() const {
442   folly::dynamic d = folly::dynamic::array(
443       folly::to<std::string>(refTime.count()),
444       "APP_LIMITED_UPDATE",
445       toString(eventType));
446   folly::dynamic data = folly::dynamic::object();
447   data["app_limited"] = limited ? kAppLimited : kAppUnlimited;
448   d.push_back(std::move(data));
449   return d;
450 }
451 
QLogBandwidthEstUpdateEvent(uint64_t bytesIn,std::chrono::microseconds intervalIn,std::chrono::microseconds refTimeIn)452 QLogBandwidthEstUpdateEvent::QLogBandwidthEstUpdateEvent(
453     uint64_t bytesIn,
454     std::chrono::microseconds intervalIn,
455     std::chrono::microseconds refTimeIn)
456     : bytes(bytesIn), interval(intervalIn) {
457   refTime = refTimeIn;
458   eventType = QLogEventType::BandwidthEstUpdate;
459 }
460 
toDynamic() const461 folly::dynamic QLogBandwidthEstUpdateEvent::toDynamic() const {
462   folly::dynamic d = folly::dynamic::array(
463       folly::to<std::string>(refTime.count()),
464       "BANDIWDTH_EST_UPDATE",
465       toString(eventType));
466   folly::dynamic data = folly::dynamic::object();
467   data["bandwidth_bytes"] = bytes;
468   data["bandwidth_interval"] = interval.count();
469   d.push_back(std::move(data));
470   return d;
471 }
472 
QLogPacingMetricUpdateEvent(uint64_t pacingBurstSizeIn,std::chrono::microseconds pacingIntervalIn,std::chrono::microseconds refTimeIn)473 QLogPacingMetricUpdateEvent::QLogPacingMetricUpdateEvent(
474     uint64_t pacingBurstSizeIn,
475     std::chrono::microseconds pacingIntervalIn,
476     std::chrono::microseconds refTimeIn)
477     : pacingBurstSize{pacingBurstSizeIn}, pacingInterval{pacingIntervalIn} {
478   eventType = QLogEventType::PacingMetricUpdate;
479   refTime = refTimeIn;
480 }
481 
toDynamic() const482 folly::dynamic QLogPacingMetricUpdateEvent::toDynamic() const {
483   // creating a folly::dynamic array to hold the information corresponding to
484   // the event fields relative_time, category, event_type, trigger, data
485   folly::dynamic d = folly::dynamic::array(
486       folly::to<std::string>(refTime.count()),
487       "metric_update",
488       toString(eventType));
489   folly::dynamic data = folly::dynamic::object();
490 
491   data["pacing_burst_size"] = pacingBurstSize;
492   data["pacing_interval"] = pacingInterval.count();
493 
494   d.push_back(std::move(data));
495   return d;
496 }
497 
QLogPacingObservationEvent(std::string actualIn,std::string expectIn,std::string conclusionIn,std::chrono::microseconds refTimeIn)498 QLogPacingObservationEvent::QLogPacingObservationEvent(
499     std::string actualIn,
500     std::string expectIn,
501     std::string conclusionIn,
502     std::chrono::microseconds refTimeIn)
503     : actual(std::move(actualIn)),
504       expect(std::move(expectIn)),
505       conclusion(std::move(conclusionIn)) {
506   eventType = QLogEventType::PacingObservation;
507   refTime = refTimeIn;
508 }
509 
510 // TODO: Sad. I wanted moved all the string into the dynamic but this function
511 // is const. I think we should make all the toDynamic rvalue qualified since
512 // users are not supposed to use them after toDynamic() is called.
toDynamic() const513 folly::dynamic QLogPacingObservationEvent::toDynamic() const {
514   folly::dynamic d = folly::dynamic::array(
515       folly::to<std::string>(refTime.count()),
516       "metric_update",
517       toString(eventType));
518   folly::dynamic data = folly::dynamic::object();
519 
520   data["actual_pacing_rate"] = actual;
521   data["expect_pacing_rate"] = expect;
522   data["conclusion"] = conclusion;
523 
524   d.push_back(std::move(data));
525   return d;
526 }
527 
QLogAppIdleUpdateEvent(std::string idleEventIn,bool idleIn,std::chrono::microseconds refTimeIn)528 QLogAppIdleUpdateEvent::QLogAppIdleUpdateEvent(
529     std::string idleEventIn,
530     bool idleIn,
531     std::chrono::microseconds refTimeIn)
532     : idleEvent{std::move(idleEventIn)}, idle{idleIn} {
533   eventType = QLogEventType::AppIdleUpdate;
534   refTime = refTimeIn;
535 }
536 
toDynamic() const537 folly::dynamic QLogAppIdleUpdateEvent::toDynamic() const {
538   // creating a folly::dynamic array to hold the information corresponding to
539   // the event fields relative_time, category, event_type, trigger, data
540   folly::dynamic d = folly::dynamic::array(
541       folly::to<std::string>(refTime.count()),
542       "idle_update",
543       toString(eventType));
544   folly::dynamic data = folly::dynamic::object();
545 
546   data["idle_event"] = idleEvent;
547   data["idle"] = idle;
548 
549   d.push_back(std::move(data));
550   return d;
551 }
552 
QLogPacketDropEvent(size_t packetSizeIn,std::string dropReasonIn,std::chrono::microseconds refTimeIn)553 QLogPacketDropEvent::QLogPacketDropEvent(
554     size_t packetSizeIn,
555     std::string dropReasonIn,
556     std::chrono::microseconds refTimeIn)
557     : packetSize{packetSizeIn}, dropReason{std::move(dropReasonIn)} {
558   eventType = QLogEventType::PacketDrop;
559   refTime = refTimeIn;
560 }
561 
toDynamic() const562 folly::dynamic QLogPacketDropEvent::toDynamic() const {
563   // creating a folly::dynamic array to hold the information corresponding to
564   // the event fields relative_time, category, event_type, trigger, data
565   folly::dynamic d = folly::dynamic::array(
566       folly::to<std::string>(refTime.count()), "loss", toString(eventType));
567   folly::dynamic data = folly::dynamic::object();
568 
569   data["packet_size"] = packetSize;
570   data["drop_reason"] = dropReason;
571 
572   d.push_back(std::move(data));
573   return d;
574 } // namespace quic
575 
QLogDatagramReceivedEvent(uint64_t dataLen,std::chrono::microseconds refTimeIn)576 QLogDatagramReceivedEvent::QLogDatagramReceivedEvent(
577     uint64_t dataLen,
578     std::chrono::microseconds refTimeIn)
579     : dataLen{dataLen} {
580   eventType = QLogEventType::DatagramReceived;
581   refTime = refTimeIn;
582 }
583 
toDynamic() const584 folly::dynamic QLogDatagramReceivedEvent::toDynamic() const {
585   // creating a folly::dynamic array to hold the information corresponding to
586   // the event fields relative_time, category, event_type, trigger, data
587   folly::dynamic d = folly::dynamic::array(
588       folly::to<std::string>(refTime.count()),
589       "transport",
590       toString(eventType));
591   folly::dynamic data = folly::dynamic::object();
592 
593   data["data_len"] = dataLen;
594 
595   d.push_back(std::move(data));
596   return d;
597 }
598 
QLogLossAlarmEvent(PacketNum largestSentIn,uint64_t alarmCountIn,uint64_t outstandingPacketsIn,std::string typeIn,std::chrono::microseconds refTimeIn)599 QLogLossAlarmEvent::QLogLossAlarmEvent(
600     PacketNum largestSentIn,
601     uint64_t alarmCountIn,
602     uint64_t outstandingPacketsIn,
603     std::string typeIn,
604     std::chrono::microseconds refTimeIn)
605     : largestSent{largestSentIn},
606       alarmCount{alarmCountIn},
607       outstandingPackets{outstandingPacketsIn},
608       type{std::move(typeIn)} {
609   eventType = QLogEventType::LossAlarm;
610   refTime = refTimeIn;
611 }
612 
toDynamic() const613 folly::dynamic QLogLossAlarmEvent::toDynamic() const {
614   // creating a folly::dynamic array to hold the information corresponding to
615   // the event fields relative_time, category, event_type, trigger, data
616   folly::dynamic d = folly::dynamic::array(
617       folly::to<std::string>(refTime.count()), "loss", toString(eventType));
618   folly::dynamic data = folly::dynamic::object();
619 
620   data["largest_sent"] = largestSent;
621   data["alarm_count"] = alarmCount;
622   data["outstanding_packets"] = outstandingPackets;
623   data["type"] = type;
624 
625   d.push_back(std::move(data));
626   return d;
627 }
628 
QLogPacketsLostEvent(PacketNum largestLostPacketNumIn,uint64_t lostBytesIn,uint64_t lostPacketsIn,std::chrono::microseconds refTimeIn)629 QLogPacketsLostEvent::QLogPacketsLostEvent(
630     PacketNum largestLostPacketNumIn,
631     uint64_t lostBytesIn,
632     uint64_t lostPacketsIn,
633     std::chrono::microseconds refTimeIn)
634     : largestLostPacketNum{largestLostPacketNumIn},
635       lostBytes{lostBytesIn},
636       lostPackets{lostPacketsIn} {
637   eventType = QLogEventType::PacketsLost;
638   refTime = refTimeIn;
639 }
640 
toDynamic() const641 folly::dynamic QLogPacketsLostEvent::toDynamic() const {
642   // creating a folly::dynamic array to hold the information corresponding to
643   // the event fields relative_time, category, event_type, trigger, data
644   folly::dynamic d = folly::dynamic::array(
645       folly::to<std::string>(refTime.count()), "loss", toString(eventType));
646   folly::dynamic data = folly::dynamic::object();
647 
648   data["largest_lost_packet_num"] = largestLostPacketNum;
649   data["lost_bytes"] = lostBytes;
650   data["lost_packets"] = lostPackets;
651 
652   d.push_back(std::move(data));
653   return d;
654 }
655 
QLogTransportStateUpdateEvent(std::string updateIn,std::chrono::microseconds refTimeIn)656 QLogTransportStateUpdateEvent::QLogTransportStateUpdateEvent(
657     std::string updateIn,
658     std::chrono::microseconds refTimeIn)
659     : update{std::move(updateIn)} {
660   eventType = QLogEventType::TransportStateUpdate;
661   refTime = refTimeIn;
662 }
663 
toDynamic() const664 folly::dynamic QLogTransportStateUpdateEvent::toDynamic() const {
665   // creating a folly::dynamic array to hold the information corresponding to
666   // the event fields relative_time, category, event_type, trigger, data
667   folly::dynamic d = folly::dynamic::array(
668       folly::to<std::string>(refTime.count()),
669       "transport",
670       toString(eventType));
671   folly::dynamic data = folly::dynamic::object();
672 
673   data["update"] = update;
674 
675   d.push_back(std::move(data));
676   return d;
677 }
678 
QLogPacketBufferedEvent(ProtectionType protectionTypeIn,uint64_t packetSizeIn,std::chrono::microseconds refTimeIn)679 QLogPacketBufferedEvent::QLogPacketBufferedEvent(
680     ProtectionType protectionTypeIn,
681     uint64_t packetSizeIn,
682     std::chrono::microseconds refTimeIn)
683     : protectionType{protectionTypeIn}, packetSize{packetSizeIn} {
684   eventType = QLogEventType::PacketBuffered;
685   refTime = refTimeIn;
686 }
687 
toDynamic() const688 folly::dynamic QLogPacketBufferedEvent::toDynamic() const {
689   // creating a folly::dynamic array to hold the information corresponding to
690   // the event fields relative_time, category, event_type, trigger, data
691   folly::dynamic d = folly::dynamic::array(
692       folly::to<std::string>(refTime.count()),
693       "transport",
694       toString(eventType));
695   folly::dynamic data = folly::dynamic::object();
696 
697   data["protection_type"] = toString(protectionType);
698   data["packet_size"] = packetSize;
699 
700   d.push_back(std::move(data));
701   return d;
702 }
703 
QLogPacketAckEvent(PacketNumberSpace packetNumSpaceIn,PacketNum packetNumIn,std::chrono::microseconds refTimeIn)704 QLogPacketAckEvent::QLogPacketAckEvent(
705     PacketNumberSpace packetNumSpaceIn,
706     PacketNum packetNumIn,
707     std::chrono::microseconds refTimeIn)
708     : packetNumSpace{packetNumSpaceIn}, packetNum{packetNumIn} {
709   eventType = QLogEventType::PacketAck;
710   refTime = refTimeIn;
711 }
712 
toDynamic() const713 folly::dynamic QLogPacketAckEvent::toDynamic() const {
714   // creating a folly::dynamic array to hold the information corresponding to
715   // the event fields relative_time, category, event_type, trigger, data
716   folly::dynamic d = folly::dynamic::array(
717       folly::to<std::string>(refTime.count()),
718       "transport",
719       toString(eventType));
720   folly::dynamic data = folly::dynamic::object();
721 
722   data["packet_num_space"] = folly::to<std::string>(packetNumSpace);
723   data["packet_num"] = packetNum;
724 
725   d.push_back(std::move(data));
726   return d;
727 }
728 
QLogMetricUpdateEvent(std::chrono::microseconds latestRttIn,std::chrono::microseconds mrttIn,std::chrono::microseconds srttIn,std::chrono::microseconds ackDelayIn,std::chrono::microseconds refTimeIn)729 QLogMetricUpdateEvent::QLogMetricUpdateEvent(
730     std::chrono::microseconds latestRttIn,
731     std::chrono::microseconds mrttIn,
732     std::chrono::microseconds srttIn,
733     std::chrono::microseconds ackDelayIn,
734     std::chrono::microseconds refTimeIn)
735     : latestRtt{latestRttIn}, mrtt{mrttIn}, srtt{srttIn}, ackDelay{ackDelayIn} {
736   eventType = QLogEventType::MetricUpdate;
737   refTime = refTimeIn;
738 }
739 
toDynamic() const740 folly::dynamic QLogMetricUpdateEvent::toDynamic() const {
741   // creating a folly::dynamic array to hold the information corresponding to
742   // the event fields relative_time, category, event_type, trigger, data
743   folly::dynamic d = folly::dynamic::array(
744       folly::to<std::string>(refTime.count()), "recovery", toString(eventType));
745   folly::dynamic data = folly::dynamic::object();
746 
747   data["latest_rtt"] = latestRtt.count();
748   data["min_rtt"] = mrtt.count();
749   data["smoothed_rtt"] = srtt.count();
750   data["ack_delay"] = ackDelay.count();
751 
752   d.push_back(std::move(data));
753   return d;
754 }
755 
QLogStreamStateUpdateEvent(StreamId idIn,std::string updateIn,folly::Optional<std::chrono::milliseconds> timeSinceStreamCreationIn,VantagePoint vantagePoint,std::chrono::microseconds refTimeIn)756 QLogStreamStateUpdateEvent::QLogStreamStateUpdateEvent(
757     StreamId idIn,
758     std::string updateIn,
759     folly::Optional<std::chrono::milliseconds> timeSinceStreamCreationIn,
760     VantagePoint vantagePoint,
761     std::chrono::microseconds refTimeIn)
762     : id{idIn},
763       update{std::move(updateIn)},
764       timeSinceStreamCreation(std::move(timeSinceStreamCreationIn)),
765       vantagePoint_(vantagePoint) {
766   eventType = QLogEventType::StreamStateUpdate;
767   refTime = refTimeIn;
768 }
769 
toDynamic() const770 folly::dynamic QLogStreamStateUpdateEvent::toDynamic() const {
771   // creating a folly::dynamic array to hold the information corresponding to
772   // the event fields relative_time, category, event_type, trigger, data
773   folly::dynamic d = folly::dynamic::array(
774       folly::to<std::string>(refTime.count()), "HTTP3", toString(eventType));
775   folly::dynamic data = folly::dynamic::object();
776 
777   data["id"] = id;
778   data["update"] = update;
779   if (timeSinceStreamCreation) {
780     if (update == kOnEOM && vantagePoint_ == VantagePoint::Client) {
781       data["ttlb"] = timeSinceStreamCreation->count();
782     } else if (update == kOnHeaders && vantagePoint_ == VantagePoint::Client) {
783       data["ttfb"] = timeSinceStreamCreation->count();
784     } else {
785       data["ms_since_creation"] = timeSinceStreamCreation->count();
786     }
787   }
788 
789   d.push_back(std::move(data));
790   return d;
791 }
792 
QLogConnectionMigrationEvent(bool intentionalMigration,VantagePoint vantagePoint,std::chrono::microseconds refTimeIn)793 QLogConnectionMigrationEvent::QLogConnectionMigrationEvent(
794     bool intentionalMigration,
795     VantagePoint vantagePoint,
796     std::chrono::microseconds refTimeIn)
797     : intentionalMigration_{intentionalMigration}, vantagePoint_(vantagePoint) {
798   eventType = QLogEventType::ConnectionMigration;
799   refTime = refTimeIn;
800 }
801 
toDynamic() const802 folly::dynamic QLogConnectionMigrationEvent::toDynamic() const {
803   // creating a folly::dynamic array to hold the information corresponding to
804   // the event fields relative_time, category, event_type, trigger, data
805   folly::dynamic d = folly::dynamic::array(
806       folly::to<std::string>(refTime.count()),
807       "transport",
808       toString(eventType));
809   folly::dynamic data = folly::dynamic::object();
810 
811   data["intentional"] = intentionalMigration_;
812   if (vantagePoint_ == VantagePoint::Client) {
813     data["type"] = "initiating";
814   } else {
815     data["type"] = "accepting";
816   }
817   d.push_back(std::move(data));
818   return d;
819 }
820 
QLogPathValidationEvent(bool success,VantagePoint vantagePoint,std::chrono::microseconds refTimeIn)821 QLogPathValidationEvent::QLogPathValidationEvent(
822     bool success,
823     VantagePoint vantagePoint,
824     std::chrono::microseconds refTimeIn)
825     : success_{success}, vantagePoint_(vantagePoint) {
826   eventType = QLogEventType::PathValidation;
827   refTime = refTimeIn;
828 }
829 
toDynamic() const830 folly::dynamic QLogPathValidationEvent::toDynamic() const {
831   // creating a folly::dynamic array to hold the information corresponding to
832   // the event fields relative_time, category, event_type, trigger, data
833   folly::dynamic d = folly::dynamic::array(
834       folly::to<std::string>(refTime.count()),
835       "transport",
836       toString(eventType));
837   folly::dynamic data = folly::dynamic::object();
838 
839   data["success"] = success_;
840   if (vantagePoint_ == VantagePoint::Client) {
841     data["vantagePoint"] = "client";
842   } else {
843     data["vantagePoint"] = "server";
844   }
845   d.push_back(std::move(data));
846   return d;
847 }
848 
QLogPriorityUpdateEvent(StreamId streamId,uint8_t urgency,bool incremental,std::chrono::microseconds refTimeIn)849 QLogPriorityUpdateEvent::QLogPriorityUpdateEvent(
850     StreamId streamId,
851     uint8_t urgency,
852     bool incremental,
853     std::chrono::microseconds refTimeIn)
854     : streamId_(streamId), urgency_(urgency), incremental_(incremental) {
855   eventType = QLogEventType::PriorityUpdate;
856   refTime = refTimeIn;
857 }
858 
toDynamic() const859 folly::dynamic QLogPriorityUpdateEvent::toDynamic() const {
860   folly::dynamic d = folly::dynamic::array(
861       folly::to<std::string>(refTime.count()), "HTTP3", toString(eventType));
862   folly::dynamic data = folly::dynamic::object();
863 
864   data["id"] = streamId_;
865   data["urgency"] = urgency_;
866   data["incremental"] = incremental_;
867   d.push_back(std::move(data));
868   return d;
869 }
870 
toString(QLogEventType type)871 folly::StringPiece toString(QLogEventType type) {
872   switch (type) {
873     case QLogEventType::PacketSent:
874       return "packet_sent";
875     case QLogEventType::PacketReceived:
876       return "packet_received";
877     case QLogEventType::ConnectionClose:
878       return "connection_close";
879     case QLogEventType::TransportSummary:
880       return "transport_summary";
881     case QLogEventType::CongestionMetricUpdate:
882       return "congestion_metric_update";
883     case QLogEventType::PacingMetricUpdate:
884       return "pacing_metric_update";
885     case QLogEventType::AppIdleUpdate:
886       return "app_idle_update";
887     case QLogEventType::PacketDrop:
888       return "packet_drop";
889     case QLogEventType::DatagramReceived:
890       return "datagram_received";
891     case QLogEventType::LossAlarm:
892       return "loss_alarm";
893     case QLogEventType::PacketsLost:
894       return "packets_lost";
895     case QLogEventType::TransportStateUpdate:
896       return "transport_state_update";
897     case QLogEventType::PacketBuffered:
898       return "packet_buffered";
899     case QLogEventType::PacketAck:
900       return "packet_ack";
901     case QLogEventType::MetricUpdate:
902       return "metric_update";
903     case QLogEventType::StreamStateUpdate:
904       return "stream_state_update";
905     case QLogEventType::PacingObservation:
906       return "pacing_observation";
907     case QLogEventType::AppLimitedUpdate:
908       return "app_limited_update";
909     case QLogEventType::BandwidthEstUpdate:
910       return "bandwidth_est_update";
911     case QLogEventType::ConnectionMigration:
912       return "connection_migration";
913     case QLogEventType::PathValidation:
914       return "path_validation";
915     case QLogEventType::PriorityUpdate:
916       return "priority";
917   }
918   folly::assume_unreachable();
919 }
920 } // namespace quic
921