From c20d7dff5121af9ae1196387b680e72a297aa115 Mon Sep 17 00:00:00 2001 From: berlin2123 <68841407+berlin2123@users.noreply.github.com> Date: Tue, 4 Mar 2025 16:24:46 +0800 Subject: [PATCH] add LogDuration --- conf/frps_full_example.toml | 2 ++ conf/legacy/frps_legacy_full.ini | 6 ++++++ pkg/config/flags.go | 1 + pkg/config/legacy/conversion.go | 1 + pkg/config/legacy/server.go | 6 ++++++ server/proxy/proxy.go | 27 ++++++++++++++++++++++++++- 6 files changed, 42 insertions(+), 1 deletion(-) diff --git a/conf/frps_full_example.toml b/conf/frps_full_example.toml index a4fc2736..b05961fd 100644 --- a/conf/frps_full_example.toml +++ b/conf/frps_full_example.toml @@ -89,6 +89,8 @@ log.level = "info" log.maxDays = 3 # disable log colors when log.to is console, default is false log.disablePrintColor = false +# log the duration of each connection name has string 'ssh' or 'rdp'. +log_duration_types = ssh,rdp # DetailedErrorsToClient defines whether to send the specific error (with debug info) to frpc. By default, this value is true. detailedErrorsToClient = true diff --git a/conf/legacy/frps_legacy_full.ini b/conf/legacy/frps_legacy_full.ini index 525072dc..b2b20f9f 100644 --- a/conf/legacy/frps_legacy_full.ini +++ b/conf/legacy/frps_legacy_full.ini @@ -70,6 +70,12 @@ log_max_days = 3 # disable log colors when log_file is console, default is false disable_log_color = false +# log the duration of each connection for the connection type identified by its name +# examples, +# 'log_duration_types = ssh,rdp', it will log the duration for connection name has string 'ssh' or 'rdp'. +# 'log_duration_types = all', it will log the duration for all connections. +log_duration_types = ssh,rdp + # DetailedErrorsToClient defines whether to send the specific error (with debug info) to frpc. By default, this value is true. detailed_errors_to_client = true diff --git a/pkg/config/flags.go b/pkg/config/flags.go index f9d9e3e4..e0014b96 100644 --- a/pkg/config/flags.go +++ b/pkg/config/flags.go @@ -241,6 +241,7 @@ func RegisterServerConfigFlags(cmd *cobra.Command, c *v1.ServerConfig, opts ...R cmd.PersistentFlags().StringVarP(&c.Log.Level, "log_level", "", "info", "log level") cmd.PersistentFlags().Int64VarP(&c.Log.MaxDays, "log_max_days", "", 3, "log max days") cmd.PersistentFlags().BoolVarP(&c.Log.DisablePrintColor, "disable_log_color", "", false, "disable log color in console") + cmd.PersistentFlags().StringVarP(&c.Log.DurationTypes, "log_duration_types", "", "ssh,rdp", "log duration types") cmd.PersistentFlags().StringVarP(&c.Auth.Token, "token", "t", "", "auth token") cmd.PersistentFlags().StringVarP(&c.SubDomainHost, "subdomain_host", "", "", "subdomain host") cmd.PersistentFlags().VarP(&PortsRangeSliceFlag{V: &c.AllowPorts}, "allow_ports", "", "allow ports") diff --git a/pkg/config/legacy/conversion.go b/pkg/config/legacy/conversion.go index dd8c4a11..43daf850 100644 --- a/pkg/config/legacy/conversion.go +++ b/pkg/config/legacy/conversion.go @@ -133,6 +133,7 @@ func Convert_ServerCommonConf_To_v1(conf *ServerCommonConf) *v1.ServerConfig { out.Log.Level = conf.LogLevel out.Log.MaxDays = conf.LogMaxDays out.Log.DisablePrintColor = conf.DisableLogColor + out.Log.DurationType = conf.LogDurationType out.DetailedErrorsToClient = lo.ToPtr(conf.DetailedErrorsToClient) out.SubDomainHost = conf.SubDomainHost diff --git a/pkg/config/legacy/server.go b/pkg/config/legacy/server.go index c58f76ad..ce74a68b 100644 --- a/pkg/config/legacy/server.go +++ b/pkg/config/legacy/server.go @@ -125,6 +125,11 @@ type ServerCommonConf struct { // DisableLogColor disables log colors when LogWay == "console" when set to // true. By default, this value is false. DisableLogColor bool `ini:"disable_log_color" json:"disable_log_color"` + // LogDurationTypes specifies the type of connection name, which will log + // the duration of those connections. if it is setting as 'ssh,rdp', it + // will log the duration of the name as 'ssh', 'ssh_1', 'sshname', 'rdp', + // 'rdp_test1' or 'web_my_rdp' . By default, this value is "ssh,rdp". + LogDurationTypes string `ini:"log_duration_types" json:"log_duration_types"` // DetailedErrorsToClient defines whether to send the specific error (with // debug info) to frpc. By default, this value is true. DetailedErrorsToClient bool `ini:"detailed_errors_to_client" json:"detailed_errors_to_client"` @@ -210,6 +215,7 @@ func GetDefaultServerConf() ServerCommonConf { DashboardAddr: "0.0.0.0", LogFile: "console", LogWay: "console", + LogDurationTypes: "ssh,rdp", DetailedErrorsToClient: true, TCPMux: true, AllowPorts: make(map[int]struct{}), diff --git a/server/proxy/proxy.go b/server/proxy/proxy.go index c7c18c32..dd2f7a72 100644 --- a/server/proxy/proxy.go +++ b/server/proxy/proxy.go @@ -21,6 +21,7 @@ import ( "net" "reflect" "strconv" + "strings" "sync" "time" @@ -258,6 +259,7 @@ func (pxy *BaseProxy) handleUserTCPConnection(userConn net.Conn) { }) } + startime := time.Now().UnixNano() / 1000000 // time in microseconds xl.Debugf("join connections, workConn(l[%s] r[%s]) userConn(l[%s] r[%s])", workConn.LocalAddr().String(), workConn.RemoteAddr().String(), userConn.LocalAddr().String(), userConn.RemoteAddr().String()) @@ -268,7 +270,30 @@ func (pxy *BaseProxy) handleUserTCPConnection(userConn net.Conn) { metrics.Server.CloseConnection(name, proxyType) metrics.Server.AddTrafficIn(name, proxyType, inCount) metrics.Server.AddTrafficOut(name, proxyType, outCount) - xl.Debugf("join connections closed") + + if IsTheTypeToLog(serverCfg.Log.DurationTypes, name) { + endtime := time.Now().UnixNano() / 1000000 // time in microseconds + connectionDuration := endtime - startime + xl.Debugf("join connection closed, it remains [%d]ms, workConn(l[%s] r[%s]) userConn(l[%s] r[%s])", connectionDuration, + workConn.LocalAddr().String(), workConn.RemoteAddr().String(), userConn.LocalAddr().String(), userConn.RemoteAddr().String()) + xl.Info("connection closed, it remains [%d]ms, userConn(l[%s] r[%s])", connectionDuration, + userConn.LocalAddr().String(), userConn.RemoteAddr().String()) + } else { + xl.Debugf("join connection closed, userConn(l[%s] r[%s])", userConn.LocalAddr().String(), userConn.RemoteAddr().String()) + } +} + +func IsTheTypeToLog(logDurationTypes string, name string) bool { + if strings.Contains(logDurationTypes, "all") { + return true + } + thestrlist := strings.Split(logDurationTypes, ",") + for i := 0; i < len(thestrlist); i++ { + if strings.Contains(name, thestrlist[i]) { + return true + } + } + return false } type Options struct {