Skip to content

Commit b94d244

Browse files
committed
Allow users to provide a custom logger
1 parent 1966301 commit b94d244

File tree

5 files changed

+304
-132
lines changed

5 files changed

+304
-132
lines changed
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
// SPDX-FileCopyrightText: 2025 The Pion community <https://pion.ly>
2+
// SPDX-License-Identifier: MIT
3+
4+
package packetdump
5+
6+
import (
7+
"fmt"
8+
"io"
9+
"sync"
10+
11+
"github.com/pion/interceptor"
12+
"github.com/pion/logging"
13+
"github.com/pion/rtcp"
14+
"github.com/pion/rtp"
15+
)
16+
17+
type defaultPacketLogger struct {
18+
log logging.LeveledLogger
19+
20+
wg sync.WaitGroup
21+
close chan struct{}
22+
23+
rtpChan chan *rtpDump
24+
rtcpChan chan *rtcpDump
25+
26+
rtpStream io.Writer
27+
rtcpStream io.Writer
28+
29+
rtpFormatBinary RTPBinaryFormatCallback
30+
rtcpFormatBinary RTCPBinaryFormatCallback
31+
32+
rtpFormat RTPFormatCallback
33+
rtcpFormat RTCPFormatCallback
34+
35+
rtpFilter RTPFilterCallback
36+
rtcpFilter RTCPFilterCallback
37+
rtcpPerPacketFilter RTCPPerPacketFilterCallback
38+
}
39+
40+
func (d *defaultPacketLogger) run() {
41+
d.wg.Add(1)
42+
go d.loop()
43+
}
44+
45+
func (d *defaultPacketLogger) LogRTPPacket(header *rtp.Header, payload []byte, attributes interceptor.Attributes) {
46+
select {
47+
case d.rtpChan <- &rtpDump{
48+
attributes: attributes,
49+
packet: &rtp.Packet{
50+
Header: *header,
51+
Payload: payload,
52+
},
53+
}:
54+
case <-d.close:
55+
}
56+
}
57+
58+
func (d *defaultPacketLogger) LogRTCPPackets(pkts []rtcp.Packet, attributes interceptor.Attributes) {
59+
select {
60+
case d.rtcpChan <- &rtcpDump{
61+
attributes: attributes,
62+
packets: pkts,
63+
}:
64+
case <-d.close:
65+
}
66+
}
67+
68+
func (d *defaultPacketLogger) writeDumpedRTP(dump *rtpDump) error {
69+
if !d.rtpFilter(dump.packet) {
70+
return nil
71+
}
72+
73+
if d.rtpFormatBinary != nil {
74+
dumped, err := d.rtpFormatBinary(dump.packet, dump.attributes)
75+
if err != nil {
76+
return fmt.Errorf("rtp format binary: %w", err)
77+
}
78+
_, err = d.rtpStream.Write(dumped)
79+
if err != nil {
80+
return fmt.Errorf("rtp stream write: %w", err)
81+
}
82+
}
83+
84+
if d.rtpFormat != nil {
85+
if _, err := fmt.Fprint(d.rtpStream, d.rtpFormat(dump.packet, dump.attributes)); err != nil {
86+
return fmt.Errorf("rtp stream Fprint: %w", err)
87+
}
88+
}
89+
90+
return nil
91+
}
92+
93+
func (d *defaultPacketLogger) writeDumpedRTCP(dump *rtcpDump) error {
94+
if !d.rtcpFilter(dump.packets) {
95+
return nil
96+
}
97+
98+
for _, pkt := range dump.packets {
99+
if !d.rtcpPerPacketFilter(pkt) {
100+
continue
101+
}
102+
103+
if d.rtcpFormatBinary != nil {
104+
dumped, err := d.rtcpFormatBinary(pkt, dump.attributes)
105+
if err != nil {
106+
return fmt.Errorf("rtcp format binary: %w", err)
107+
}
108+
109+
_, err = d.rtcpStream.Write(dumped)
110+
if err != nil {
111+
return fmt.Errorf("rtcp stream write: %w", err)
112+
}
113+
}
114+
}
115+
116+
if d.rtcpFormat != nil {
117+
if _, err := fmt.Fprint(d.rtcpStream, d.rtcpFormat(dump.packets, dump.attributes)); err != nil {
118+
return fmt.Errorf("rtcp stream Fprint: %w", err)
119+
}
120+
}
121+
122+
return nil
123+
}
124+
125+
// Close closes the PacketDumper.
126+
func (d *defaultPacketLogger) Close() error {
127+
defer d.wg.Wait()
128+
129+
if !d.isClosed() {
130+
close(d.close)
131+
}
132+
133+
return nil
134+
}
135+
136+
func (d *defaultPacketLogger) isClosed() bool {
137+
select {
138+
case <-d.close:
139+
return true
140+
default:
141+
return false
142+
}
143+
}
144+
145+
func (d *defaultPacketLogger) loop() {
146+
defer d.wg.Done()
147+
148+
for {
149+
select {
150+
case <-d.close:
151+
return
152+
case dump := <-d.rtpChan:
153+
err := d.writeDumpedRTP(dump)
154+
if err != nil {
155+
d.log.Errorf("could not dump RTP packet: %v", err)
156+
}
157+
case dump := <-d.rtcpChan:
158+
err := d.writeDumpedRTCP(dump)
159+
if err != nil {
160+
d.log.Errorf("could not dump RTCP packets: %v", err)
161+
}
162+
}
163+
}
164+
}

pkg/packetdump/option.go

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,18 @@ func Log(log logging.LeveledLogger) PacketDumperOption {
2121
}
2222
}
2323

24-
// RTPWriter sets the io.Writer on which RTP packets will be dumped.
24+
// PacketLog sets the packet logger of a packet dumper. Use this to replace the
25+
// default logger with yout own logger implementation.
26+
func PacketLog(logger PacketLogger) PacketDumperOption {
27+
return func(d *PacketDumper) error {
28+
d.packetLogger = logger
29+
30+
return nil
31+
}
32+
}
33+
34+
// RTPWriter sets the io.Writer on which RTP packets will be dumped by the
35+
// default packet logger.
2536
func RTPWriter(w io.Writer) PacketDumperOption {
2637
return func(d *PacketDumper) error {
2738
d.rtpStream = w
@@ -30,7 +41,8 @@ func RTPWriter(w io.Writer) PacketDumperOption {
3041
}
3142
}
3243

33-
// RTCPWriter sets the io.Writer on which RTCP packets will be dumped.
44+
// RTCPWriter sets the io.Writer on which RTCP packets will be dumped by the
45+
// default packet logger.
3446
func RTCPWriter(w io.Writer) PacketDumperOption {
3547
return func(d *PacketDumper) error {
3648
d.rtcpStream = w
@@ -39,7 +51,7 @@ func RTCPWriter(w io.Writer) PacketDumperOption {
3951
}
4052
}
4153

42-
// RTPFormatter sets the RTP format
54+
// RTPFormatter sets the RTP format used by the default packet logger.
4355
// Deprecated: prefer RTPBinaryFormatter.
4456
func RTPFormatter(f RTPFormatCallback) PacketDumperOption {
4557
return func(d *PacketDumper) error {
@@ -49,7 +61,7 @@ func RTPFormatter(f RTPFormatCallback) PacketDumperOption {
4961
}
5062
}
5163

52-
// RTCPFormatter sets the RTCP format
64+
// RTCPFormatter sets the RTCP format used by the default packet logger.
5365
// Deprecated: prefer RTCPBinaryFormatter.
5466
func RTCPFormatter(f RTCPFormatCallback) PacketDumperOption {
5567
return func(d *PacketDumper) error {
@@ -59,7 +71,8 @@ func RTCPFormatter(f RTCPFormatCallback) PacketDumperOption {
5971
}
6072
}
6173

62-
// RTPBinaryFormatter sets the RTP binary formatter.
74+
// RTPBinaryFormatter sets the RTP binary formatter used by the default packet
75+
// logger.
6376
func RTPBinaryFormatter(f RTPBinaryFormatCallback) PacketDumperOption {
6477
return func(d *PacketDumper) error {
6578
d.rtpFormatBinary = f
@@ -68,7 +81,8 @@ func RTPBinaryFormatter(f RTPBinaryFormatCallback) PacketDumperOption {
6881
}
6982
}
7083

71-
// RTCPBinaryFormatter sets the RTCP binary formatter.
84+
// RTCPBinaryFormatter sets the RTCP binary formatter used by the default packet
85+
// logger.
7286
func RTCPBinaryFormatter(f RTCPBinaryFormatCallback) PacketDumperOption {
7387
return func(d *PacketDumper) error {
7488
d.rtcpFormatBinary = f
@@ -77,7 +91,7 @@ func RTCPBinaryFormatter(f RTCPBinaryFormatCallback) PacketDumperOption {
7791
}
7892
}
7993

80-
// RTPFilter sets the RTP filter.
94+
// RTPFilter sets the RTP filter used by the default packet logger.
8195
func RTPFilter(callback RTPFilterCallback) PacketDumperOption {
8296
return func(d *PacketDumper) error {
8397
d.rtpFilter = callback
@@ -86,7 +100,7 @@ func RTPFilter(callback RTPFilterCallback) PacketDumperOption {
86100
}
87101
}
88102

89-
// RTCPFilter sets the RTCP filter.
103+
// RTCPFilter sets the RTCP filter used by the default packet logger.
90104
// Deprecated: prefer RTCPPerPacketFilter.
91105
func RTCPFilter(callback RTCPFilterCallback) PacketDumperOption {
92106
return func(d *PacketDumper) error {
@@ -96,7 +110,8 @@ func RTCPFilter(callback RTCPFilterCallback) PacketDumperOption {
96110
}
97111
}
98112

99-
// RTCPPerPacketFilter sets the RTCP per-packet filter.
113+
// RTCPPerPacketFilter sets the RTCP per-packet filter used by the default
114+
// packet logger.
100115
func RTCPPerPacketFilter(callback RTCPPerPacketFilterCallback) PacketDumperOption {
101116
return func(d *PacketDumper) error {
102117
d.rtcpPerPacketFilter = callback

0 commit comments

Comments
 (0)