diff --git a/app/dispatcher/default.go b/app/dispatcher/default.go index 1531866f4..86cab6be0 100644 --- a/app/dispatcher/default.go +++ b/app/dispatcher/default.go @@ -154,12 +154,15 @@ func (d *DefaultDispatcher) getLink(ctx context.Context) (*transport.Link, *tran if user != nil && len(user.Email) > 0 { p := d.policy.ForLevel(user.Level) + accessMessage := log.AccessMessageFromContext(ctx) + if p.Stats.UserUplink { name := "user>>>" + user.Email + ">>>traffic>>>uplink" if c, _ := stats.GetOrRegisterCounter(d.stats, name); c != nil { inboundLink.Writer = &SizeStatWriter{ Counter: c, Writer: inboundLink.Writer, + Record: &accessMessage.BytesSent, } } } @@ -169,6 +172,7 @@ func (d *DefaultDispatcher) getLink(ctx context.Context) (*transport.Link, *tran outboundLink.Writer = &SizeStatWriter{ Counter: c, Writer: outboundLink.Writer, + Record: &accessMessage.BytesReceived, } } } @@ -285,12 +289,12 @@ func (d *DefaultDispatcher) routedDispatch(ctx context.Context, link *transport. return } + handler.Dispatch(ctx, link) + if accessMessage := log.AccessMessageFromContext(ctx); accessMessage != nil { if tag := handler.Tag(); tag != "" { accessMessage.Detour = tag } log.Record(accessMessage) } - - handler.Dispatch(ctx, link) } diff --git a/app/dispatcher/stats.go b/app/dispatcher/stats.go index 9b1c3a063..da73fdd33 100644 --- a/app/dispatcher/stats.go +++ b/app/dispatcher/stats.go @@ -11,10 +11,15 @@ import ( type SizeStatWriter struct { Counter stats.Counter Writer buf.Writer + Record *int64 } func (w *SizeStatWriter) WriteMultiBuffer(mb buf.MultiBuffer) error { - w.Counter.Add(int64(mb.Len())) + bufLen := int64(mb.Len()) + if w.Record != nil { + *w.Record += bufLen + } + w.Counter.Add(bufLen) return w.Writer.WriteMultiBuffer(mb) } diff --git a/common/log/access.go b/common/log/access.go index 789426d92..b44f616ec 100644 --- a/common/log/access.go +++ b/common/log/access.go @@ -2,6 +2,7 @@ package log import ( "context" + "fmt" "strings" "v2ray.com/core/common/serial" @@ -21,12 +22,14 @@ const ( ) type AccessMessage struct { - From interface{} - To interface{} - Status AccessStatus - Reason interface{} - Email string - Detour string + From interface{} + To interface{} + Status AccessStatus + Reason interface{} + Email string + Detour string + BytesSent int64 + BytesReceived int64 } func (m *AccessMessage) String() string { @@ -53,6 +56,8 @@ func (m *AccessMessage) String() string { builder.WriteString(m.Email) } + builder.WriteString(fmt.Sprintf(" bytes_sent: %d bytes_received: %d", m.BytesSent, m.BytesReceived)) + return builder.String() }