github.com/pion/webrtc/v4@v4.0.1/examples/custom-logger/main.go (about)

     1  // SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
     2  // SPDX-License-Identifier: MIT
     3  
     4  //go:build !js
     5  // +build !js
     6  
     7  // custom-logger is an example of how the Pion API provides an customizable logging API
     8  package main
     9  
    10  import (
    11  	"fmt"
    12  	"os"
    13  
    14  	"github.com/pion/logging"
    15  	"github.com/pion/webrtc/v4"
    16  )
    17  
    18  // Everything below is the Pion WebRTC API! Thanks for using it ❤️.
    19  
    20  // customLogger satisfies the interface logging.LeveledLogger
    21  // a logger is created per subsystem in Pion, so you can have custom
    22  // behavior per subsystem (ICE, DTLS, SCTP...)
    23  type customLogger struct{}
    24  
    25  // Print all messages except trace
    26  func (c customLogger) Trace(string)                  {}
    27  func (c customLogger) Tracef(string, ...interface{}) {}
    28  
    29  func (c customLogger) Debug(msg string) { fmt.Printf("customLogger Debug: %s\n", msg) }
    30  func (c customLogger) Debugf(format string, args ...interface{}) {
    31  	c.Debug(fmt.Sprintf(format, args...))
    32  }
    33  func (c customLogger) Info(msg string) { fmt.Printf("customLogger Info: %s\n", msg) }
    34  func (c customLogger) Infof(format string, args ...interface{}) {
    35  	c.Trace(fmt.Sprintf(format, args...))
    36  }
    37  func (c customLogger) Warn(msg string) { fmt.Printf("customLogger Warn: %s\n", msg) }
    38  func (c customLogger) Warnf(format string, args ...interface{}) {
    39  	c.Warn(fmt.Sprintf(format, args...))
    40  }
    41  func (c customLogger) Error(msg string) { fmt.Printf("customLogger Error: %s\n", msg) }
    42  func (c customLogger) Errorf(format string, args ...interface{}) {
    43  	c.Error(fmt.Sprintf(format, args...))
    44  }
    45  
    46  // customLoggerFactory satisfies the interface logging.LoggerFactory
    47  // This allows us to create different loggers per subsystem. So we can
    48  // add custom behavior
    49  type customLoggerFactory struct{}
    50  
    51  func (c customLoggerFactory) NewLogger(subsystem string) logging.LeveledLogger {
    52  	fmt.Printf("Creating logger for %s \n", subsystem)
    53  	return customLogger{}
    54  }
    55  
    56  func main() {
    57  	// Create a new API with a custom logger
    58  	// This SettingEngine allows non-standard WebRTC behavior
    59  	s := webrtc.SettingEngine{
    60  		LoggerFactory: customLoggerFactory{},
    61  	}
    62  	api := webrtc.NewAPI(webrtc.WithSettingEngine(s))
    63  
    64  	// Create a new RTCPeerConnection
    65  	offerPeerConnection, err := api.NewPeerConnection(webrtc.Configuration{})
    66  	if err != nil {
    67  		panic(err)
    68  	}
    69  	defer func() {
    70  		if cErr := offerPeerConnection.Close(); cErr != nil {
    71  			fmt.Printf("cannot close offerPeerConnection: %v\n", cErr)
    72  		}
    73  	}()
    74  
    75  	// We need a DataChannel so we can have ICE Candidates
    76  	if _, err = offerPeerConnection.CreateDataChannel("custom-logger", nil); err != nil {
    77  		panic(err)
    78  	}
    79  
    80  	// Create a new RTCPeerConnection
    81  	answerPeerConnection, err := api.NewPeerConnection(webrtc.Configuration{})
    82  	if err != nil {
    83  		panic(err)
    84  	}
    85  	defer func() {
    86  		if cErr := answerPeerConnection.Close(); cErr != nil {
    87  			fmt.Printf("cannot close answerPeerConnection: %v\n", cErr)
    88  		}
    89  	}()
    90  
    91  	// Set the handler for Peer connection state
    92  	// This will notify you when the peer has connected/disconnected
    93  	offerPeerConnection.OnConnectionStateChange(func(s webrtc.PeerConnectionState) {
    94  		fmt.Printf("Peer Connection State has changed: %s (offerer)\n", s.String())
    95  
    96  		if s == webrtc.PeerConnectionStateFailed {
    97  			// Wait until PeerConnection has had no network activity for 30 seconds or another failure. It may be reconnected using an ICE Restart.
    98  			// Use webrtc.PeerConnectionStateDisconnected if you are interested in detecting faster timeout.
    99  			// Note that the PeerConnection may come back from PeerConnectionStateDisconnected.
   100  			fmt.Println("Peer Connection has gone to failed exiting")
   101  			os.Exit(0)
   102  		}
   103  
   104  		if s == webrtc.PeerConnectionStateClosed {
   105  			// PeerConnection was explicitly closed. This usually happens from a DTLS CloseNotify
   106  			fmt.Println("Peer Connection has gone to closed exiting")
   107  			os.Exit(0)
   108  		}
   109  	})
   110  
   111  	// Set the handler for Peer connection state
   112  	// This will notify you when the peer has connected/disconnected
   113  	answerPeerConnection.OnConnectionStateChange(func(s webrtc.PeerConnectionState) {
   114  		fmt.Printf("Peer Connection State has changed: %s (answerer)\n", s.String())
   115  
   116  		if s == webrtc.PeerConnectionStateFailed {
   117  			// Wait until PeerConnection has had no network activity for 30 seconds or another failure. It may be reconnected using an ICE Restart.
   118  			// Use webrtc.PeerConnectionStateDisconnected if you are interested in detecting faster timeout.
   119  			// Note that the PeerConnection may come back from PeerConnectionStateDisconnected.
   120  			fmt.Println("Peer Connection has gone to failed exiting")
   121  			os.Exit(0)
   122  		}
   123  	})
   124  
   125  	// Set ICE Candidate handler. As soon as a PeerConnection has gathered a candidate
   126  	// send it to the other peer
   127  	answerPeerConnection.OnICECandidate(func(i *webrtc.ICECandidate) {
   128  		if i != nil {
   129  			if iceErr := offerPeerConnection.AddICECandidate(i.ToJSON()); iceErr != nil {
   130  				panic(iceErr)
   131  			}
   132  		}
   133  	})
   134  
   135  	// Set ICE Candidate handler. As soon as a PeerConnection has gathered a candidate
   136  	// send it to the other peer
   137  	offerPeerConnection.OnICECandidate(func(i *webrtc.ICECandidate) {
   138  		if i != nil {
   139  			if iceErr := answerPeerConnection.AddICECandidate(i.ToJSON()); iceErr != nil {
   140  				panic(iceErr)
   141  			}
   142  		}
   143  	})
   144  
   145  	// Create an offer for the other PeerConnection
   146  	offer, err := offerPeerConnection.CreateOffer(nil)
   147  	if err != nil {
   148  		panic(err)
   149  	}
   150  
   151  	// SetLocalDescription, needed before remote gets offer
   152  	if err = offerPeerConnection.SetLocalDescription(offer); err != nil {
   153  		panic(err)
   154  	}
   155  
   156  	// Take offer from remote, answerPeerConnection is now able to contact
   157  	// the other PeerConnection
   158  	if err = answerPeerConnection.SetRemoteDescription(offer); err != nil {
   159  		panic(err)
   160  	}
   161  
   162  	// Create an Answer to send back to our originating PeerConnection
   163  	answer, err := answerPeerConnection.CreateAnswer(nil)
   164  	if err != nil {
   165  		panic(err)
   166  	}
   167  
   168  	// Set the answerer's LocalDescription
   169  	if err = answerPeerConnection.SetLocalDescription(answer); err != nil {
   170  		panic(err)
   171  	}
   172  
   173  	// SetRemoteDescription on original PeerConnection, this finishes our signaling
   174  	// bother PeerConnections should be able to communicate with each other now
   175  	if err = offerPeerConnection.SetRemoteDescription(answer); err != nil {
   176  		panic(err)
   177  	}
   178  
   179  	// Block forever
   180  	select {}
   181  }