diff --git a/modules/log/groutinelabel.go b/modules/log/groutinelabel.go
new file mode 100644
index 0000000000..0d3739fd98
--- /dev/null
+++ b/modules/log/groutinelabel.go
@@ -0,0 +1,20 @@
+// Copyright 2022 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package log
+
+import "unsafe"
+
+//go:linkname runtime_getProfLabel runtime/pprof.runtime_getProfLabel
+func runtime_getProfLabel() unsafe.Pointer // nolint
+
+type labelMap map[string]string
+
+func getGoroutineLabels() map[string]string {
+	l := (*labelMap)(runtime_getProfLabel())
+	if l == nil {
+		return nil
+	}
+	return *l
+}
diff --git a/modules/log/groutinelabel_test.go b/modules/log/groutinelabel_test.go
new file mode 100644
index 0000000000..8e23721b86
--- /dev/null
+++ b/modules/log/groutinelabel_test.go
@@ -0,0 +1,34 @@
+// Copyright 2022 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package log
+
+import (
+	"context"
+	"runtime/pprof"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func Test_getGoroutineLabels(t *testing.T) {
+	pprof.Do(context.Background(), pprof.Labels(), func(ctx context.Context) {
+		currentLabels := getGoroutineLabels()
+		pprof.ForLabels(ctx, func(key, value string) bool {
+			assert.EqualValues(t, value, currentLabels[key])
+			return true
+		})
+
+		pprof.Do(ctx, pprof.Labels("Test_getGoroutineLabels", "Test_getGoroutineLabels_child1"), func(ctx context.Context) {
+			currentLabels := getGoroutineLabels()
+			pprof.ForLabels(ctx, func(key, value string) bool {
+				assert.EqualValues(t, value, currentLabels[key])
+				return true
+			})
+			if assert.NotNil(t, currentLabels) {
+				assert.EqualValues(t, "Test_getGoroutineLabels_child1", currentLabels["Test_getGoroutineLabels"])
+			}
+		})
+	})
+}
diff --git a/modules/log/multichannel.go b/modules/log/multichannel.go
index c725df4f3e..8d94eb2b22 100644
--- a/modules/log/multichannel.go
+++ b/modules/log/multichannel.go
@@ -72,6 +72,13 @@ func (l *MultiChannelledLogger) Log(skip int, level Level, format string, v ...i
 	if len(v) > 0 {
 		msg = ColorSprintf(format, v...)
 	}
+	labels := getGoroutineLabels()
+	if labels != nil {
+		pid, ok := labels["pid"]
+		if ok {
+			msg = "[" + ColorString(FgHiYellow) + pid + ColorString(Reset) + "] " + msg
+		}
+	}
 	stack := ""
 	if l.GetStacktraceLevel() <= level {
 		stack = Stack(skip + 1)