package canonicallog

import (
	
	
	
	
	
	
	

	

	logging 
	
	manet 
)

var log = slog.New(
	slog.NewTextHandler(
		os.Stderr,
		&slog.HandlerOptions{
			Level:     logging.ConfigFromEnv().LevelForSystem("canonical-log"),
			AddSource: true}))

// logWithSkip logs at level with AddSource pointing to the caller `skip` frames up
// from *this* function’s caller (so skip=0 => the immediate caller of logWithSkip).
func logWithSkip( context.Context,  *slog.Logger,  slog.Level,  int,  string,  ...any) {
	if !.Enabled(, ) {
		return
	}

	var  [1]uintptr
	// +2 to skip runtime.Callers and logWithSkip itself.
	runtime.Callers(+2, [:])

	 := slog.NewRecord(time.Now(), , , [0])
	.Add(...)
	_ = .Handler().Handle(, )
}

// LogMisbehavingPeer is the canonical way to log a misbehaving peer.
// Protocols should use this to identify a misbehaving peer to allow the end
// user to easily identify these nodes across protocols and libp2p.
func ( peer.ID,  multiaddr.Multiaddr,  string,  error,  string) {
	logWithSkip(context.Background(), log, slog.LevelWarn, 1, "CANONICAL_MISBEHAVING_PEER",
		"peer", ,
		"addr", ,
		"component", ,
		"err", ,
		"msg", )
}

// LogMisbehavingPeerNetAddr is the canonical way to log a misbehaving peer.
// Protocols should use this to identify a misbehaving peer to allow the end
// user to easily identify these nodes across protocols and libp2p.
func ( peer.ID,  net.Addr,  string,  error,  string) {
	,  := manet.FromNetAddr()
	if  != nil {
		logWithSkip(context.Background(), log, slog.LevelWarn, 1, "CANONICAL_MISBEHAVING_PEER",
			"peer", ,
			"net_addr", .String(),
			"component", ,
			"err", ,
			"msg", )
		return
	}

	LogMisbehavingPeer(, , , , )
}

// LogPeerStatus logs any useful information about a peer. It takes in a sample
// rate and will only log one in every sampleRate messages (randomly). This is
// useful in surfacing events that are normal in isolation, but may be abnormal
// in large quantities. For example, a successful connection from an IP address
// is normal. 10,000 connections from that same IP address is not normal. libp2p
// itself does nothing besides emitting this log. Hook this up to another tool
// like fail2ban to action on the log.
func ( int,  peer.ID,  multiaddr.Multiaddr,  ...string) {
	if rand.Intn() == 0 {
		 := []any{
			"peer", ,
			"addr", .String(),
			"sample_rate", ,
		}
		// Add the additional key-value pairs
		for ,  := range  {
			 = append(, )
		}
		logWithSkip(context.Background(), log, slog.LevelInfo, 1, "CANONICAL_PEER_STATUS", ...)
	}
}