parent
80d23bb340
commit
0b2a2a4d44
@ -0,0 +1,104 @@ |
||||
package sls |
||||
|
||||
import ( |
||||
"encoding/json" |
||||
"time" |
||||
|
||||
sls "github.com/aliyun/aliyun-log-go-sdk" |
||||
"google.golang.org/protobuf/proto" |
||||
) |
||||
|
||||
// GenerateLog 传入固定请求日志,生成sls对应格式日志
|
||||
func GenerateLog(request *Request) *sls.Log { |
||||
var log sls.Log |
||||
// 获取当前时间
|
||||
log.Time = proto.Uint32(uint32(time.Now().Unix())) |
||||
contents := make([]*sls.LogContent, 0) |
||||
// time
|
||||
contents = append(contents, &sls.LogContent{ |
||||
Key: proto.String("time"), |
||||
Value: proto.String(request.Time.Format("2006-01-02 15:04:05")), |
||||
}) |
||||
// remote_addr
|
||||
contents = append(contents, &sls.LogContent{ |
||||
Key: proto.String("remote_addr"), |
||||
Value: proto.String(request.RemoteAddr), |
||||
}) |
||||
// query_string
|
||||
contents = append(contents, &sls.LogContent{ |
||||
Key: proto.String("query_string"), |
||||
Value: proto.String(request.QueryString), |
||||
}) |
||||
// request_method
|
||||
contents = append(contents, &sls.LogContent{ |
||||
Key: proto.String("request_method"), |
||||
Value: proto.String(request.RequestMethod), |
||||
}) |
||||
// request_uri
|
||||
contents = append(contents, &sls.LogContent{ |
||||
Key: proto.String("request_uri"), |
||||
Value: proto.String(request.RequestUri), |
||||
}) |
||||
// host
|
||||
contents = append(contents, &sls.LogContent{ |
||||
Key: proto.String("host"), |
||||
Value: proto.String(request.Host), |
||||
}) |
||||
// request_body
|
||||
contents = append(contents, &sls.LogContent{ |
||||
Key: proto.String("request_body"), |
||||
Value: proto.String(request.RequestBody), |
||||
}) |
||||
// http_user_agent
|
||||
contents = append(contents, &sls.LogContent{ |
||||
Key: proto.String("http_user_agent"), |
||||
Value: proto.String(request.HttpUserAgent), |
||||
}) |
||||
// http_finger
|
||||
contents = append(contents, &sls.LogContent{ |
||||
Key: proto.String("http_finger"), |
||||
Value: proto.String(request.HttpFinger), |
||||
}) |
||||
// http_referrer
|
||||
contents = append(contents, &sls.LogContent{ |
||||
Key: proto.String("http_referrer"), |
||||
Value: proto.String(request.HttpReferrer), |
||||
}) |
||||
// http_trace_id
|
||||
contents = append(contents, &sls.LogContent{ |
||||
Key: proto.String("http_trace_id"), |
||||
Value: proto.String(request.HttpTraceId), |
||||
}) |
||||
// x_app_id
|
||||
contents = append(contents, &sls.LogContent{ |
||||
Key: proto.String("x_app_id"), |
||||
Value: proto.String(request.XAppId), |
||||
}) |
||||
// x_user_data
|
||||
userData, _ := json.Marshal(request.XUserData) |
||||
contents = append(contents, &sls.LogContent{ |
||||
Key: proto.String("x_user_data"), |
||||
Value: proto.String(string(userData)), |
||||
}) |
||||
// x_dsm_data
|
||||
dsmData, _ := json.Marshal(request.XDsmData) |
||||
contents = append(contents, &sls.LogContent{ |
||||
Key: proto.String("x_dsm_data"), |
||||
Value: proto.String(string(dsmData)), |
||||
}) |
||||
// http_trace_id
|
||||
customData, _ := json.Marshal(request.XCustomData) |
||||
contents = append(contents, &sls.LogContent{ |
||||
Key: proto.String("x_custom_data"), |
||||
Value: proto.String(string(customData)), |
||||
}) |
||||
// response_data
|
||||
respData, _ := json.Marshal(request.ResponseData) |
||||
contents = append(contents, &sls.LogContent{ |
||||
Key: proto.String("response_data"), |
||||
Value: proto.String(string(respData)), |
||||
}) |
||||
|
||||
log.Contents = contents |
||||
return &log |
||||
} |
@ -0,0 +1,123 @@ |
||||
package sls |
||||
|
||||
import ( |
||||
"gitea.drugeyes.vip/pharnexbase/utils/enum" |
||||
sls "github.com/aliyun/aliyun-log-go-sdk" |
||||
"github.com/aliyun/aliyun-log-go-sdk/producer" |
||||
) |
||||
|
||||
type options struct { |
||||
accessKey string |
||||
accessSecret string |
||||
endpoint string |
||||
project string |
||||
logstore string |
||||
} |
||||
|
||||
func defaultOptions() *options { |
||||
return &options{ |
||||
project: "bcpm-log", |
||||
logstore: "request-develop", |
||||
} |
||||
} |
||||
|
||||
// WithEndpoint 指定端口
|
||||
func WithEndpoint(endpoint string) Option { |
||||
return func(alc *options) { |
||||
alc.endpoint = endpoint |
||||
} |
||||
} |
||||
|
||||
// WithProject 指定发送普通日志的project
|
||||
func WithProject(project string) Option { |
||||
return func(alc *options) { |
||||
alc.project = project |
||||
} |
||||
} |
||||
|
||||
// WithLogstore 指定发送普通日志的logstore
|
||||
func WithLogstore(logstore string) Option { |
||||
return func(alc *options) { |
||||
alc.logstore = logstore |
||||
} |
||||
} |
||||
|
||||
// WithAccessKey 设置访问access id
|
||||
func WithAccessKey(ak string) Option { |
||||
return func(alc *options) { |
||||
alc.accessKey = ak |
||||
} |
||||
} |
||||
|
||||
// WithAccessSecret 设置访问access secret
|
||||
func WithAccessSecret(as string) Option { |
||||
return func(alc *options) { |
||||
alc.accessSecret = as |
||||
} |
||||
} |
||||
|
||||
type Option func(alc *options) |
||||
|
||||
type slsProducer struct { |
||||
pr *producer.Producer |
||||
opts *options |
||||
} |
||||
|
||||
// NewSLSProducer 创建一个高性能的sls制造者
|
||||
func NewSLSProducer(opts ...Option) *slsProducer { |
||||
opt := defaultOptions() |
||||
|
||||
for _, o := range opts { |
||||
o(opt) |
||||
} |
||||
|
||||
producerConfig := producer.GetDefaultProducerConfig() |
||||
producerConfig.Endpoint = opt.endpoint |
||||
producerConfig.AccessKeyID = opt.accessKey |
||||
producerConfig.AccessKeySecret = opt.accessSecret |
||||
producerInstance := producer.InitProducer(producerConfig) |
||||
|
||||
producerInstance.Start() |
||||
return &slsProducer{ |
||||
pr: producerInstance, |
||||
opts: opt, |
||||
} |
||||
} |
||||
|
||||
// Close 程序结束时,必须调用该方法,不然可能导致部分日志丢失
|
||||
func (s *slsProducer) Close() error { |
||||
return s.pr.Close(5000) |
||||
} |
||||
|
||||
// SendLog 发送普通日志
|
||||
func (s *slsProducer) SendLog(log *sls.Log) error { |
||||
err := s.pr.SendLog(s.opts.project, s.opts.logstore, "", "", log) |
||||
if err != nil { |
||||
return err |
||||
} |
||||
return nil |
||||
} |
||||
|
||||
// SendRequestLog 发送特定的请求日志,使用该方法时,不需要指定project和logstore
|
||||
func (s *slsProducer) SendRequestLog(env enum.Env, req *Request) error { |
||||
log := GenerateLog(req) |
||||
|
||||
err := s.pr.SendLog("bcpm-log", getLogStore(env), "", "", log) |
||||
if err != nil { |
||||
return err |
||||
} |
||||
return nil |
||||
} |
||||
|
||||
func getLogStore(env enum.Env) string { |
||||
switch env { |
||||
case enum.Env_local, enum.Env_develop: |
||||
return "request-develop" |
||||
case enum.Env_preview: |
||||
return "request-preview" |
||||
case enum.Env_production: |
||||
return "request" |
||||
default: |
||||
return "request-develop" |
||||
} |
||||
} |
@ -0,0 +1,60 @@ |
||||
package sls |
||||
|
||||
import ( |
||||
"testing" |
||||
"time" |
||||
|
||||
"gitea.drugeyes.vip/pharnexbase/utils/enum" |
||||
) |
||||
|
||||
var pd *slsProducer |
||||
|
||||
func init() { |
||||
pd = NewSLSProducer( |
||||
WithEndpoint("cn-hangzhou.log.aliyuncs.com"), |
||||
WithAccessKey("-"), // 传入阿里云sls的key
|
||||
WithAccessSecret("-"), // 传入阿里云sls的Secret
|
||||
) |
||||
} |
||||
|
||||
func TestProducer(t *testing.T) { |
||||
err := pd.SendRequestLog(enum.Env_develop, &Request{ |
||||
Time: time.Now(), |
||||
RemoteAddr: "118.112.98.208", |
||||
QueryString: "test001", |
||||
RequestMethod: "POST", |
||||
RequestUri: "/dc/analyse/senior_aggregation", |
||||
Host: "intsynth-server.drugeyes.vip", |
||||
RequestBody: "{}", |
||||
HttpUserAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 OPR/99.0.0.0", |
||||
HttpFinger: "59246b1e1639f4753bcd010bac2ddb01", |
||||
HttpReferrer: "http://intsynth-web.drugeyes.vip:7031/", |
||||
HttpTraceId: "0121", |
||||
XAppId: "LtEolTiV", |
||||
XUserData: &UserData{ |
||||
ID: "1075", |
||||
Username: "用户名_IDdXdk4xSU", |
||||
OrganizeID: "223", |
||||
OrganizeName: "新数据-机构06-权限", |
||||
Email: "", |
||||
Phone: "17800000051", |
||||
}, |
||||
XDsmData: &DSMData{ |
||||
AppKey: "ce2f8bcc2f64466d", |
||||
PageType: "LIST", |
||||
DataCount: 1, |
||||
DBData: make([]*DBCount, 0), |
||||
}, |
||||
XCustomData: nil, |
||||
ResponseData: nil, |
||||
}) |
||||
if err != nil { |
||||
t.Fail() |
||||
} |
||||
|
||||
err = pd.Close() |
||||
if err != nil { |
||||
t.Fail() |
||||
} |
||||
|
||||
} |
@ -0,0 +1,46 @@ |
||||
package sls |
||||
|
||||
import "time" |
||||
|
||||
// Request HTTP请求
|
||||
type Request struct { |
||||
Time time.Time `json:"time"` // 请求时间
|
||||
RemoteAddr string `json:"remote_addr"` // 客户IP
|
||||
QueryString string `json:"query_string"` // Query参数
|
||||
RequestMethod string `json:"request_method"` // 请求方法
|
||||
RequestUri string `json:"request_uri"` // 请求地址
|
||||
Host string `json:"host"` // host地址
|
||||
RequestBody string `json:"request_body"` // 请求body
|
||||
HttpUserAgent string `json:"http_user_agent"` // 浏览器标识
|
||||
HttpFinger string `json:"http_finger"` // 浏览器指纹
|
||||
HttpReferrer string `json:"http_referrer"` // referer信息
|
||||
HttpTraceId string `json:"http_trace_id"` // trance信息
|
||||
XAppId string `json:"x_app_id"` // 用户中心的应用ID
|
||||
XUserData *UserData `json:"x_user_data"` // 用户信息
|
||||
XDsmData *DSMData `json:"x_dsm_data"` // 风控信息,不接人风控可不传入
|
||||
XCustomData any `json:"x_custom_data"` // 自定义信息,需要能够转为json字符串
|
||||
ResponseData any `json:"response_data"` // 返回信息
|
||||
} |
||||
|
||||
// UserData 用户数据
|
||||
type UserData struct { |
||||
ID string `json:"id"` // 用户ID
|
||||
Username string `json:"username"` // 用户名称
|
||||
OrganizeID string `json:"organize_id"` // 组织ID
|
||||
OrganizeName string `json:"organize_name"` // 组织名称
|
||||
Phone string `json:"phone"` // 手机号
|
||||
Email string `json:"email"` // 邮箱
|
||||
} |
||||
|
||||
type DBCount struct { |
||||
DB string `json:"db"` // 数据库标识
|
||||
UniqueKey string `json:"unique_key"` // 该条记录唯一标识
|
||||
} |
||||
|
||||
// DSMData 风控需要数据
|
||||
type DSMData struct { |
||||
AppKey string `json:"app_key"` // 项目在风控平台的appid
|
||||
PageType string `json:"page_type"` // 访问类型
|
||||
DataCount int32 `json:"data_count"` // 请求数量,list的时为列表数据量
|
||||
DBData []*DBCount `json:"db_data"` // 数据库监控时,对应数据相关内容
|
||||
} |
Loading…
Reference in new issue