Repository: etcd-io/etcd
File: server/embed/config_logging.go (Go)

Code before:
				encoder = zapcore.NewConsoleEncoder(logutil.DefaultZapLoggerConfig.EncoderConfig)
			} else {
				encoder = zapcore.NewJSONEncoder(logutil.DefaultZapLoggerConfig.EncoderConfig)
			}

			// WARN: do not change field names in encoder config
			// journald logging writer assumes field names of "level" and "caller"
			cr := zapcore.NewCore(
				encoder,
				syncer,
				lvl,
			)
			if cfg.ZapLoggerBuilder == nil {
				cfg.ZapLoggerBuilder = NewZapLoggerBuilder(zap.New(cr, zap.AddCaller(), zap.ErrorOutput(syncer)))
			}
		}

		err := cfg.ZapLoggerBuilder(cfg)
		if err != nil {
			return err
		}

		logTLSHandshakeFailureFunc := func(msg string) func(conn *tls.Conn, err error) {
			return func(conn *tls.Conn, err error) {
				state := conn.ConnectionState()
				remoteAddr := conn.RemoteAddr().String()
				serverName := state.ServerName
				if len(state.PeerCertificates) > 0 {
					cert := state.PeerCertificates[0]
					ips := make([]string, len(cert.IPAddresses))
					for i := range cert.IPAddresses {
						ips[i] = cert.IPAddresses[i].String()
					}
					cfg.logger.Warn(
						msg,
						zap.String("remote-addr", remoteAddr),
						zap.String("server-name", serverName),
						zap.Strings("ip-addresses", ips),
						zap.Strings("dns-names", cert.DNSNames),
						zap.Error(err),
					)
				} else {
					cfg.logger.Warn(
						msg,
						zap.String("remote-addr", remoteAddr),
						zap.String("server-name", serverName),
						zap.Error(err),
					)
				}
			}
		}

Review comment (bug):
I am not sure it's good idea to eat EOF error by debug mode. 
It's unlikely to enable debug mode and wait for it to reproduce it.
At least, it's handshake failure.

Code after:
				encoder = zapcore.NewConsoleEncoder(logutil.DefaultZapLoggerConfig.EncoderConfig)
			} else {
				encoder = zapcore.NewJSONEncoder(logutil.DefaultZapLoggerConfig.EncoderConfig)
			}

			// WARN: do not change field names in encoder config
			// journald logging writer assumes field names of "level" and "caller"
			cr := zapcore.NewCore(
				encoder,
				syncer,
				lvl,
			)
			if cfg.ZapLoggerBuilder == nil {
				cfg.ZapLoggerBuilder = NewZapLoggerBuilder(zap.New(cr, zap.AddCaller(), zap.ErrorOutput(syncer)))
			}
		}

		err := cfg.ZapLoggerBuilder(cfg)
		if err != nil {
			return err
		}

		logTLSHandshakeFailureFunc := func(msg string) func(conn *tls.Conn, err error) {
			return func(conn *tls.Conn, err error) {
				// Log EOF errors on DEBUG not to spam logs too much.
				logFunc := cfg.logger.Warn
				if errors.Is(err, io.EOF) {
					logFunc = cfg.logger.Debug
				}

				state := conn.ConnectionState()
				remoteAddr := conn.RemoteAddr().String()
				serverName := state.ServerName
				if len(state.PeerCertificates) > 0 {
					cert := state.PeerCertificates[0]
					ips := make([]string, len(cert.IPAddresses))
					for i := range cert.IPAddresses {
						ips[i] = cert.IPAddresses[i].String()
					}
					logFunc(
						msg,
						zap.String("remote-addr", remoteAddr),
						zap.String("server-name", serverName),
						zap.Strings("ip-addresses", ips),
						zap.Strings("dns-names", cert.DNSNames),
						zap.Error(err),
					)
				} else {
					logFunc(
						msg,
						zap.String("remote-addr", remoteAddr),