├── .idea ├── .gitignore ├── vcs.xml ├── modules.xml └── gologstash.iml ├── type.go ├── go.mod ├── example └── e1 │ └── main.go ├── README.md ├── logstash.go ├── gostash.go └── go.sum /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # 默认忽略的文件 2 | /shelf/ 3 | /workspace.xml 4 | # 基于编辑器的 HTTP 客户端请求 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /type.go: -------------------------------------------------------------------------------- 1 | package gostash 2 | 3 | import "github.com/silenceper/pool" 4 | 5 | type GoStash struct { 6 | Pool pool.Pool 7 | } 8 | 9 | type Protocol string 10 | 11 | const ( 12 | TCP Protocol = "tcp" 13 | ) 14 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/soxft/gostash 2 | 3 | go 1.22.3 4 | 5 | require ( 6 | github.com/pkg/errors v0.9.1 7 | github.com/silenceper/pool v1.0.0 8 | ) 9 | 10 | require ( 11 | github.com/sirupsen/logrus v1.9.3 // indirect 12 | golang.org/x/sys v0.21.0 // indirect 13 | ) 14 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/gologstash.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/e1/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/soxft/gostash" 5 | "log" 6 | ) 7 | 8 | func main() { 9 | pool, err := gostash.New("logstash.com", 50000, gostash.TCP, gostash.DefaultPoolConfig()) 10 | if err != nil { 11 | log.Fatalf("logstash connect failed: %s", err) 12 | } 13 | 14 | pool.StringLog("{'name':'xcsoft','url':'https://github.com/soxft/gostash'}") 15 | } 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # gostash 2 | > send logs to logstash from golang, connection pool supported 3 | 4 | # install 5 | > go get github.com/soxft/gostash 6 | 7 | # usage 8 | 9 | ```go 10 | pool, err := gostash.New("logstash.com", 50000, gostash.TCP, gostash.DefaultPoolConfig()) 11 | if err != nil { 12 | log.Fatalf("logstash connect failed: %s", err) 13 | } 14 | 15 | pool.StringLog("{'name':'xcsoft','url':'https://github.com/soxft/gostash'}") 16 | ``` 17 | 18 | -------------------------------------------------------------------------------- /logstash.go: -------------------------------------------------------------------------------- 1 | package gostash 2 | 3 | import ( 4 | "log" 5 | "net" 6 | ) 7 | 8 | func (l *GoStash) StringLog(str string) { 9 | connection, err := l.Pool.Get() 10 | if err != nil { 11 | log.Println("[Logstash Logger] Failed to get connection from pool: ", err) 12 | return 13 | } 14 | 15 | _, connWriteError := connection.(net.Conn).Write([]byte(str)) 16 | if connWriteError != nil { 17 | log.Printf("[Logstash Logger] Failed to send log String message: %s\n", connWriteError) 18 | } 19 | 20 | defer func() { 21 | _ = connection.(net.Conn).Close() 22 | }() 23 | } 24 | -------------------------------------------------------------------------------- /gostash.go: -------------------------------------------------------------------------------- 1 | package gostash 2 | 3 | import ( 4 | "fmt" 5 | "github.com/pkg/errors" 6 | "github.com/silenceper/pool" 7 | "net" 8 | "time" 9 | ) 10 | 11 | func DefaultPoolConfig() pool.Config { 12 | return pool.Config{ 13 | InitialCap: 5, // 资源池初始连接数 14 | MaxIdle: 20, // 最大空闲连接数 15 | MaxCap: 30, // 最大并发连接数 16 | IdleTimeout: 15 * time.Second, 17 | } 18 | } 19 | 20 | func New( 21 | Host string, 22 | Port int, 23 | Protocol Protocol, 24 | config pool.Config, 25 | ) (*GoStash, error) { 26 | 27 | if Protocol != TCP { 28 | return nil, fmt.Errorf("unsupported protocol: %s", Protocol) 29 | } 30 | 31 | factory := func() (interface{}, error) { return net.Dial("tcp", fmt.Sprintf("%s:%d", Host, Port)) } 32 | clo := func(v interface{}) error { return v.(net.Conn).Close() } 33 | 34 | //ping 检测连接的方法 35 | //ping := func(v interface{}) error { return nil } 36 | 37 | //创建一个连接池: 初始化5,最大空闲连接是20,最大并发连接30 38 | config.Factory = factory 39 | config.Close = clo 40 | p, err := pool.NewChannelPool(&config) 41 | if err != nil { 42 | return nil, errors.Wrap(err, "pool init failed") 43 | } 44 | 45 | return &GoStash{ 46 | Pool: p, 47 | }, nil 48 | } 49 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 2 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 3 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 4 | github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= 5 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 6 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 7 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 8 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 9 | github.com/silenceper/pool v1.0.0 h1:JTCaA+U6hJAA0P8nCx+JfsRCHMwLTfatsm5QXelffmU= 10 | github.com/silenceper/pool v1.0.0/go.mod h1:3DN13bqAbq86Lmzf6iUXWEPIWFPOSYVfaoceFvilKKI= 11 | github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= 12 | github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= 13 | github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= 14 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 15 | github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 16 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= 17 | github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= 18 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 19 | golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 20 | golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 21 | golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= 22 | golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 23 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 24 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= 25 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 26 | --------------------------------------------------------------------------------