Skip to content

Commit 5396364

Browse files
authored
Merge pull request #5 from devfeel/aicode
feat: add JSON structured log target
2 parents d2d1158 + 6f84b43 commit 5396364

19 files changed

Lines changed: 734 additions & 26 deletions

File tree

.github/workflows/ci.yml

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [master, develop, aicode]
6+
pull_request:
7+
branches: [aicode]
8+
9+
jobs:
10+
test:
11+
name: Test
12+
runs-on: ubuntu-latest
13+
14+
steps:
15+
- name: Checkout code
16+
uses: actions/checkout@v4
17+
18+
- name: Set up Go
19+
uses: actions/setup-go@v5
20+
with:
21+
go-version: '1.18'
22+
cache: true
23+
24+
- name: Download dependencies
25+
run: go mod download
26+
27+
- name: Build
28+
run: go build -v ./...
29+
30+
- name: Run tests
31+
run: go test -v -race -coverprofile=coverage.out ./...
32+
33+
- name: Upload coverage
34+
uses: actions/upload-artifact@v4
35+
with:
36+
name: coverage
37+
path: coverage.out
38+
39+
lint:
40+
name: Lint
41+
runs-on: ubuntu-latest
42+
43+
steps:
44+
- name: Checkout code
45+
uses: actions/checkout@v4
46+
47+
- name: Set up Go
48+
uses: actions/setup-go@v5
49+
with:
50+
go-version: '1.18'
51+
cache: true
52+
53+
- name: Run golangci-lint
54+
uses: golangci/golangci-lint-action@v6
55+
with:
56+
version: latest

config/config.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ type (
6060
UdpTargets []*UdpTargetConfig `xml:"udp>target"`
6161
HttpTargets []*HttpTargetConfig `xml:"http>target"`
6262
EMailTargets []*EMailTargetConfig `xml:"email>target"`
63-
FmtTargets []*FmtTargetConfig `xml:"fmt>target"`
63+
FmtTargets []*FmtTargetConfig `xml:"fmt>target"`
64+
JSONTargets []*JSONTargetConfig `xml:"json>target"`
6465
}
6566

6667
FileTargetConfig struct {

config/config.yaml

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# dotlog YAML 配置文件示例
2+
# 使用说明: 将文件名传递给 StartLogService("config.yaml") 即可
3+
4+
global:
5+
isLog: true
6+
chanSize: 1000
7+
innerLogPath: "./"
8+
innerLogEncode: "utf-8"
9+
10+
# 自定义变量
11+
variables:
12+
- name: LogDir
13+
value: "./logs/"
14+
- name: LogDateDir
15+
value: "./logs/{year}/{month}/{day}/"
16+
17+
# 日志输出目标
18+
targets:
19+
# 文件输出
20+
file:
21+
- name: FileLogger
22+
isLog: true
23+
layout: "{datetime} - {message}"
24+
encode: "utf-8"
25+
fileMaxSize: 10240 # KB
26+
fileName: "./logs/app.log"
27+
28+
# 标准输出
29+
fmt:
30+
- name: StdoutLogger
31+
isLog: true
32+
layout: "[{level}] {datetime} - {message}"
33+
encode: "utf-8"
34+
35+
# UDP 输出 (可选)
36+
# udp:
37+
# - name: UdpLogger
38+
# isLog: true
39+
# layout: "{message}"
40+
# encode: "utf-8"
41+
# remoteIP: "127.0.0.1:9000"
42+
43+
# HTTP 输出 (可选)
44+
# http:
45+
# - name: HttpLogger
46+
# isLog: true
47+
# layout: "{message}"
48+
# encode: "utf-8"
49+
# httpUrl: "http://localhost:8080/log"
50+
51+
# 日志记录器配置
52+
loggers:
53+
- name: FileLogger
54+
isLog: true
55+
layout: "{datetime} - {message}"
56+
configMode: "file"
57+
levels:
58+
- level: info
59+
targets: "FileLogger"
60+
isLog: true
61+
- level: error
62+
targets: "FileLogger"
63+
isLog: true
64+
65+
- name: StdoutLogger
66+
isLog: true
67+
layout: "[{level}] {datetime} - {message}"
68+
configMode: "fmt"
69+
levels:
70+
- level: debug
71+
targets: "StdoutLogger"
72+
isLog: true
73+
- level: info
74+
targets: "StdoutLogger"
75+
isLog: true

config/json.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package config
2+
3+
// JSONTargetConfig JSON 输出目标配置
4+
type JSONTargetConfig struct {
5+
Name string `yaml:"name"`
6+
IsLog bool `yaml:"isLog"`
7+
Layout string `yaml:"layout"`
8+
Encode string `yaml:"encode"`
9+
FileName string `yaml:"fileName"`
10+
FileMaxSize int64 `yaml:"fileMaxSize"`
11+
PrettyPrint *bool `yaml:"prettyPrint"`
12+
}

config/json_test.go

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package config
2+
3+
import (
4+
"os"
5+
"path/filepath"
6+
"testing"
7+
)
8+
9+
func TestLoadYamlConfigWithJSON(t *testing.T) {
10+
tmpDir := t.TempDir()
11+
configFile := filepath.Join(tmpDir, "test.json.yaml")
12+
13+
yamlContent := `
14+
global:
15+
isLog: true
16+
chanSize: 1000
17+
innerLogPath: "./"
18+
innerLogEncode: "utf-8"
19+
20+
targets:
21+
json:
22+
- name: JSONLogger
23+
isLog: true
24+
layout: "{datetime} - {message}"
25+
encode: "utf-8"
26+
fileName: "./logs/app.json"
27+
fileMaxSize: 10240
28+
prettyPrint: true
29+
30+
loggers:
31+
- name: JSONLogger
32+
isLog: true
33+
layout: "{datetime} - {message}"
34+
configMode: "json"
35+
levels:
36+
- level: info
37+
targets: "JSONLogger"
38+
isLog: true
39+
`
40+
err := os.WriteFile(configFile, []byte(yamlContent), 0644)
41+
if err != nil {
42+
t.Fatalf("failed to create test config: %v", err)
43+
}
44+
45+
config, err := LoadYamlConfig(configFile)
46+
if err != nil {
47+
t.Fatalf("failed to load YAML config: %v", err)
48+
}
49+
50+
// Verify JSON targets
51+
if len(config.Targets.JSONTargets) != 1 {
52+
t.Errorf("expected 1 JSON target, got %d", len(config.Targets.JSONTargets))
53+
}
54+
55+
jsonTarget := config.Targets.JSONTargets[0]
56+
if jsonTarget.Name != "JSONLogger" {
57+
t.Errorf("expected target name JSONLogger, got %s", jsonTarget.Name)
58+
}
59+
if jsonTarget.FileName != "./logs/app.json" {
60+
t.Errorf("expected fileName ./logs/app.json, got %s", jsonTarget.FileName)
61+
}
62+
if jsonTarget.FileMaxSize != 10240 {
63+
t.Errorf("expected fileMaxSize 10240, got %d", jsonTarget.FileMaxSize)
64+
}
65+
if jsonTarget.PrettyPrint == nil || !*jsonTarget.PrettyPrint {
66+
t.Error("expected prettyPrint to be true")
67+
}
68+
}

0 commit comments

Comments
 (0)