Skip to content

Commit

Permalink
[logger] move QuicFileLogger into the library
Browse files Browse the repository at this point in the history
  • Loading branch information
jlaine committed Oct 27, 2021
1 parent 1e599cb commit bf7f409
Show file tree
Hide file tree
Showing 10 changed files with 85 additions and 64 deletions.
4 changes: 2 additions & 2 deletions examples/doq_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
from typing import Optional, cast

from dnslib.dns import QTYPE, DNSQuestion, DNSRecord
from quic_logger import QuicDirectoryLogger

from aioquic.asyncio.client import connect
from aioquic.asyncio.protocol import QuicConnectionProtocol
from aioquic.quic.configuration import QuicConfiguration
from aioquic.quic.events import QuicEvent, StreamDataReceived
from aioquic.quic.logger import QuicFileLogger

logger = logging.getLogger("client")

Expand Down Expand Up @@ -134,7 +134,7 @@ async def run(
if args.insecure:
configuration.verify_mode = ssl.CERT_NONE
if args.quic_log:
configuration.quic_logger = QuicDirectoryLogger(args.quic_log)
configuration.quic_logger = QuicFileLogger(args.quic_log)
if args.secrets_log:
configuration.secrets_log_file = open(args.secrets_log, "a")
if args.session_ticket:
Expand Down
4 changes: 2 additions & 2 deletions examples/doq_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
from typing import Dict, Optional

from dnslib.dns import DNSRecord
from quic_logger import QuicDirectoryLogger

from aioquic.asyncio import QuicConnectionProtocol, serve
from aioquic.quic.configuration import QuicConfiguration
from aioquic.quic.connection import QuicConnection
from aioquic.quic.events import ProtocolNegotiated, QuicEvent, StreamDataReceived
from aioquic.quic.logger import QuicFileLogger
from aioquic.tls import SessionTicket

try:
Expand Down Expand Up @@ -127,7 +127,7 @@ def pop(self, label: bytes) -> Optional[SessionTicket]:
)

if args.quic_log:
quic_logger = QuicDirectoryLogger(args.quic_log)
quic_logger = QuicFileLogger(args.quic_log)
else:
quic_logger = None

Expand Down
4 changes: 2 additions & 2 deletions examples/http3_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@

import wsproto
import wsproto.events
from quic_logger import QuicDirectoryLogger

import aioquic
from aioquic.asyncio.client import connect
Expand All @@ -26,6 +25,7 @@
)
from aioquic.quic.configuration import QuicConfiguration
from aioquic.quic.events import QuicEvent
from aioquic.quic.logger import QuicFileLogger
from aioquic.tls import CipherSuite, SessionTicket

try:
Expand Down Expand Up @@ -504,7 +504,7 @@ async def run(
if args.max_stream_data:
configuration.max_stream_data = args.max_stream_data
if args.quic_log:
configuration.quic_logger = QuicDirectoryLogger(args.quic_log)
configuration.quic_logger = QuicFileLogger(args.quic_log)
if args.secrets_log:
configuration.secrets_log_file = open(args.secrets_log, "a")
if args.session_ticket:
Expand Down
4 changes: 2 additions & 2 deletions examples/http3_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@

import wsproto
import wsproto.events
from quic_logger import QuicDirectoryLogger

import aioquic
from aioquic.asyncio import QuicConnectionProtocol, serve
Expand All @@ -25,6 +24,7 @@
from aioquic.h3.exceptions import NoAvailablePushIDError
from aioquic.quic.configuration import QuicConfiguration
from aioquic.quic.events import DatagramFrameReceived, ProtocolNegotiated, QuicEvent
from aioquic.quic.logger import QuicFileLogger
from aioquic.tls import SessionTicket

try:
Expand Down Expand Up @@ -543,7 +543,7 @@ def pop(self, label: bytes) -> Optional[SessionTicket]:

# create QUIC logger
if args.quic_log:
quic_logger = QuicDirectoryLogger(args.quic_log)
quic_logger = QuicFileLogger(args.quic_log)
else:
quic_logger = None

Expand Down
4 changes: 2 additions & 2 deletions examples/httpx_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@

import httpcore
from httpx import AsyncClient
from quic_logger import QuicDirectoryLogger

from aioquic.asyncio.client import connect
from aioquic.asyncio.protocol import QuicConnectionProtocol
from aioquic.h3.connection import H3_ALPN, H3Connection
from aioquic.h3.events import DataReceived, H3Event, Headers, HeadersReceived
from aioquic.quic.configuration import QuicConfiguration
from aioquic.quic.events import QuicEvent
from aioquic.quic.logger import QuicFileLogger

logger = logging.getLogger("client")

Expand Down Expand Up @@ -277,7 +277,7 @@ async def run(
if args.insecure:
configuration.verify_mode = ssl.CERT_NONE
if args.quic_log:
configuration.quic_logger = QuicDirectoryLogger(args.quic_log)
configuration.quic_logger = QuicFileLogger(args.quic_log)
if args.secrets_log:
configuration.secrets_log_file = open(args.secrets_log, "a")
if args.session_ticket:
Expand Down
5 changes: 2 additions & 3 deletions examples/interop.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,13 @@

import httpx
from http3_client import HttpClient
from quic_logger import QuicDirectoryLogger

from aioquic.asyncio import connect
from aioquic.h0.connection import H0_ALPN
from aioquic.h3.connection import H3_ALPN, H3Connection
from aioquic.h3.events import DataReceived, HeadersReceived, PushPromiseReceived
from aioquic.quic.configuration import QuicConfiguration
from aioquic.quic.logger import QuicLogger
from aioquic.quic.logger import QuicFileLogger, QuicLogger


class Result(Flag):
Expand Down Expand Up @@ -505,7 +504,7 @@ async def run(servers, tests, quic_log=False, secrets_log_file=None) -> None:
configuration = QuicConfiguration(
alpn_protocols=H3_ALPN + H0_ALPN,
is_client=True,
quic_logger=QuicDirectoryLogger(quic_log) if quic_log else QuicLogger(),
quic_logger=QuicFileLogger(quic_log) if quic_log else QuicLogger(),
secrets_log_file=secrets_log_file,
verify_mode=server.verify_mode,
)
Expand Down
25 changes: 0 additions & 25 deletions examples/quic_logger.py

This file was deleted.

5 changes: 2 additions & 3 deletions examples/siduck_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,11 @@
import ssl
from typing import Optional, cast

from quic_logger import QuicDirectoryLogger

from aioquic.asyncio.client import connect
from aioquic.asyncio.protocol import QuicConnectionProtocol
from aioquic.quic.configuration import QuicConfiguration
from aioquic.quic.events import DatagramFrameReceived, QuicEvent
from aioquic.quic.logger import QuicFileLogger

logger = logging.getLogger("client")

Expand Down Expand Up @@ -88,7 +87,7 @@ async def run(configuration: QuicConfiguration, host: str, port: int) -> None:
if args.insecure:
configuration.verify_mode = ssl.CERT_NONE
if args.quic_log:
configuration.quic_logger = QuicDirectoryLogger(args.quic_log)
configuration.quic_logger = QuicFileLogger(args.quic_log)
if args.secrets_log:
configuration.secrets_log_file = open(args.secrets_log, "a")

Expand Down
23 changes: 23 additions & 0 deletions src/aioquic/quic/logger.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import binascii
import json
import os
import time
from collections import deque
from typing import Any, Deque, Dict, List, Optional, Tuple
Expand Down Expand Up @@ -267,3 +269,24 @@ def to_dict(self) -> Dict[str, Any]:
"qlog_version": "draft-01",
"traces": [trace.to_dict() for trace in self._traces],
}


class QuicFileLogger(QuicLogger):
"""
A QUIC event logger which writes one trace per file.
"""

def __init__(self, path: str) -> None:
if not os.path.isdir(path):
raise ValueError("QUIC log output directory '%s' does not exist" % path)
self.path = path
super().__init__()

def end_trace(self, trace: QuicLoggerTrace) -> None:
trace_dict = trace.to_dict()
trace_path = os.path.join(
self.path, trace_dict["common_fields"]["ODCID"] + ".qlog"
)
with open(trace_path, "w") as logger_fp:
json.dump({"qlog_version": "draft-01", "traces": [trace_dict]}, logger_fp)
self._traces.remove(trace)
71 changes: 48 additions & 23 deletions tests/test_logger.py
Original file line number Diff line number Diff line change
@@ -1,37 +1,62 @@
import json
import os
import tempfile
from unittest import TestCase

from aioquic.quic.logger import QuicLogger
from aioquic.quic.logger import QuicFileLogger, QuicLogger

SINGLE_TRACE = {
"qlog_version": "draft-01",
"traces": [
{
"common_fields": {
"ODCID": "0000000000000000",
"reference_time": "0",
},
"configuration": {"time_units": "us"},
"event_fields": [
"relative_time",
"category",
"event_type",
"data",
],
"events": [],
"vantage_point": {"name": "aioquic", "type": "client"},
}
],
}


class QuicLoggerTest(TestCase):
def test_empty(self):
logger = QuicLogger()
self.assertEqual(logger.to_dict(), {"qlog_version": "draft-01", "traces": []})

def test_empty_trace(self):
def test_single_trace(self):
logger = QuicLogger()
trace = logger.start_trace(is_client=True, odcid=bytes(8))
logger.end_trace(trace)
self.assertEqual(logger.to_dict(), SINGLE_TRACE)


class QuicFileLoggerTest(TestCase):
def test_invalid_path(self):
with self.assertRaises(ValueError) as cm:
QuicFileLogger("this_path_should_not_exist")
self.assertEqual(
logger.to_dict(),
{
"qlog_version": "draft-01",
"traces": [
{
"common_fields": {
"ODCID": "0000000000000000",
"reference_time": "0",
},
"configuration": {"time_units": "us"},
"event_fields": [
"relative_time",
"category",
"event_type",
"data",
],
"events": [],
"vantage_point": {"name": "aioquic", "type": "client"},
}
],
},
str(cm.exception),
"QUIC log output directory 'this_path_should_not_exist' does not exist",
)

def test_single_trace(self):
with tempfile.TemporaryDirectory() as dirpath:
logger = QuicFileLogger(dirpath)
trace = logger.start_trace(is_client=True, odcid=bytes(8))
logger.end_trace(trace)

filepath = os.path.join(dirpath, "0000000000000000.qlog")
self.assertTrue(os.path.exists(filepath))

with open(filepath, "r") as fp:
data = json.load(fp)
self.assertEqual(data, SINGLE_TRACE)

0 comments on commit bf7f409

Please sign in to comment.