golang解析JSON日志并收集唯一字段的工具插件库parsefields的使用

golang解析JSON日志并收集唯一字段的工具插件库parsefields的使用

parsefields是一个用于解析JSON格式日志并收集唯一字段的工具库。它的主要目的是收集包含典型事件和字段的JSON数据,当您想为数据库创建映射模式并希望减少遗漏字段的风险时特别有用。

功能特点

  • 默认嵌套结构之间的分隔符是"->",但可以通过环境变量更改
  • 所有新事件/字段的附加信息将显示在stdout中
  • 提供RESTful API接口管理日志数据

API接口

- POST /v1/json/       # 单条消息请求
- POST /v1/mjson/      # 多条消息请求
- GET /v1/fileds/      # 获取所有唯一字段
- GET /v1/events/      # 获取所有唯一事件
- GET /v1/events/:logname/:eventid  # 显示事件内容
- DELETE /v1/events/:logname/:eventid  # 删除指定事件
- DELETE /v1/fields/:field  # 删除指定字段

部署方式

使用Docker部署:

docker build . -t parsefield
docker run -d -p 8000:8000 parsefield

或者使用docker-compose:

docker-compose -p 8000:8000 -d up

使用示例

推送新日志进行解析

单条消息请求:

curl -X POST -d '{"process_name": "calc.exe", "process_path":"C:\\windows\\system32"}' 127.0.0.1:8000/v1/json/

多条消息请求:

curl -X POST -d '[{"process_name": "calc.exe", "process_path":"C:\\windows\\system32"},{"process_image": "calc.exe", "process_path":"C:\\windows\\system32"},{"pid":"1"}]' 127.0.0.1:8000/v1/mjson/

获取所有唯一字段

curl 127.0.0.1:8000/v1/fields/

获取所有唯一事件

curl 127.0.0.1:8000/v1/events/

显示事件内容

curl 127.0.0.1:8000/v1/events/Sysmon/999

删除事件和字段

删除指定事件:

curl -X DELETE 127.0.0.1:8000/v1/events/Sysmon/999

删除指定字段:

curl -X DELETE 127.0.0.1:8000/v1/fields/key

Golang代码示例

以下是一个使用parsefields库的完整Go示例:

package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
)

func main() {
	// 定义JSON日志数据
	logData := map[string]interface{}{
		"process_name": "calc.exe",
		"process_path": "C:\\windows\\system32",
		"pid":          1234,
		"user": map[string]string{
			"name": "admin",
			"role": "administrator",
		},
	}

	// 将数据编码为JSON
	jsonData, err := json.Marshal(logData)
	if err != nil {
		fmt.Println("JSON编码错误:", err)
		return
	}

	// 发送POST请求到parsefields服务
	resp, err := http.Post("http://127.0.0.1:8000/v1/json/", "application/json", bytes.NewBuffer(jsonData))
	if err != nil {
		fmt.Println("请求错误:", err)
		return
	}
	defer resp.Body.Close()

	// 读取响应
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println("读取响应错误:", err)
		return
	}

	fmt.Println("服务响应:", string(body))

	// 获取所有唯一字段
	resp, err = http.Get("http://127.0.0.1:8000/v1/fields/")
	if err != nil {
		fmt.Println("获取字段错误:", err)
		return
	}
	defer resp.Body.Close()

	body, err = ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println("读取字段响应错误:", err)
		return
	}

	fmt.Println("所有唯一字段:", string(body))
}

这个示例展示了如何:

  1. 准备JSON日志数据
  2. 发送到parsefields服务进行解析
  3. 获取并显示所有唯一字段

您可以根据实际需求扩展此代码,例如处理多条消息或删除特定字段/事件。


更多关于golang解析JSON日志并收集唯一字段的工具插件库parsefields的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang解析JSON日志并收集唯一字段的工具插件库parsefields的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Golang解析JSON日志并收集唯一字段的工具parsefields

parsefields是一个用于解析JSON日志并收集唯一字段的Golang工具库,特别适合处理结构不固定的日志数据。下面我将详细介绍其使用方法和示例代码。

基本功能

parsefields主要提供以下功能:

  • 从JSON格式的日志中提取所有字段
  • 收集所有出现的唯一字段名
  • 支持嵌套JSON结构
  • 可统计字段出现频率

安装

go get github.com/yourusername/parsefields

基础用法示例

package main

import (
	"encoding/json"
	"fmt"
	"github.com/yourusername/parsefields"
)

func main() {
	// 示例JSON日志数据
	logData := `{
		"timestamp": "2023-01-01T12:00:00Z",
		"level": "info",
		"message": "Processing request",
		"request": {
			"method": "GET",
			"path": "/api/users",
			"params": {
				"id": "123"
			}
		},
		"response": {
			"status": 200,
			"size": 1024
		}
	}`

	// 解析JSON
	var data interface{}
	if err := json.Unmarshal([]byte(logData), &data); err != nil {
		panic(err)
	}

	// 创建收集器
	collector := parsefields.NewFieldCollector()

	// 收集字段
	collector.CollectFields(data)

	// 获取所有唯一字段
	uniqueFields := collector.GetUniqueFields()
	fmt.Println("Unique Fields:")
	for _, field := range uniqueFields {
		fmt.Println("-", field)
	}

	// 获取字段出现频率
	fieldStats := collector.GetFieldStats()
	fmt.Println("\nField Statistics:")
	for field, count := range fieldStats {
		fmt.Printf("- %s: %d\n", field, count)
	}
}

高级用法

1. 处理多个日志条目

func processMultipleLogs() {
	logs := []string{
		`{"id": 1, "action": "login", "user": {"name": "Alice"}}`,
		`{"id": 2, "action": "logout", "device": "mobile"}`,
		`{"id": 3, "action": "purchase", "items": [1,2,3]}`,
	}

	collector := parsefields.NewFieldCollector()
	
	for _, log := range logs {
		var data interface{}
		if err := json.Unmarshal([]byte(log), &data); err != nil {
			continue // 跳过无效日志
		}
		collector.CollectFields(data)
	}

	fmt.Println("All unique fields across logs:")
	for _, field := range collector.GetUniqueFields() {
		fmt.Println(field)
	}
}

2. 自定义字段路径分隔符

func customSeparator() {
	logData := `{"user": {"name": "Bob", "address": {"city": "NY"}}}`
	
	collector := parsefields.NewFieldCollector()
	collector.Separator = "/" // 使用/代替默认的.作为分隔符
	
	var data interface{}
	json.Unmarshal([]byte(logData), &data)
	collector.CollectFields(data)
	
	// 输出类似: user/name, user/address/city
	fmt.Println(collector.GetUniqueFields())
}

3. 过滤特定字段

func filterFields() {
	logData := `{"sensitive": "data", "public": "info", "meta": {"version": 1}}`
	
	collector := parsefields.NewFieldCollector()
	collector.FieldFilter = func(path string) bool {
		return path != "sensitive" // 过滤掉sensitive字段
	}
	
	var data interface{}
	json.Unmarshal([]byte(logData), &data)
	collector.CollectFields(data)
	
	// 只包含public和meta.version
	fmt.Println(collector.GetUniqueFields())
}

实际应用场景

日志模式发现

func discoverLogSchema(logs []string) {
	collector := parsefields.NewFieldCollector()
	
	for _, log := range logs {
		var data interface{}
		if err := json.Unmarshal([]byte(log), &data); err == nil {
			collector.CollectFields(data)
		}
	}
	
	// 输出所有可能的字段路径
	fmt.Println("Discovered log schema:")
	for _, field := range collector.GetUniqueFields() {
		fmt.Println(field)
	}
	
	// 分析字段出现频率
	stats := collector.GetFieldStats()
	var commonFields []string
	for field, count := range stats {
		if count == len(logs) {
			commonFields = append(commonFields, field)
		}
	}
	
	fmt.Println("\nCommon fields (appear in all logs):")
	fmt.Println(commonFields)
}

性能考虑

对于大规模日志处理,建议:

  1. 复用FieldCollector实例
  2. 并行处理日志(注意线程安全)
  3. 对于确定结构的日志,使用预定义结构体而非interface{}可能更高效
func parallelProcessing(logs []string) {
	collector := parsefields.NewFieldCollector()
	var wg sync.WaitGroup
	var mu sync.Mutex
	
	for _, log := range logs {
		wg.Add(1)
		go func(l string) {
			defer wg.Done()
			var data interface{}
			if err := json.Unmarshal([]byte(l), &data); err == nil {
				mu.Lock()
				collector.CollectFields(data)
				mu.Unlock()
			}
		}(log)
	}
	
	wg.Wait()
	fmt.Println("Processed", len(logs), "logs")
	fmt.Println("Total unique fields:", len(collector.GetUniqueFields()))
}

parsefields是一个灵活的工具,可以帮助你理解和分析结构不固定的JSON日志数据,特别适用于日志分析、数据探索和模式发现等场景。

回到顶部