Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,22 @@ git clone --depth 1 [email protected]:simagix/hatchet.git
cd hatchet ; ./build.sh
```

An executable *hatchet* is output to the directory *dist/*.
An executable *hatchet* is output to the directory *dist/*. Note that the script also works and tested on Windows x64 using MingGW and Git Bash.

## Quick Start
Use the command below to process a log file, mongod.log.gz and start a web server listening to port 3721.
Use the command below to process a log file, mongod.log.gz and start a web server listening to port 3721. The default database is SQLite3.
```bash
./dist/hatchet -web mongod.log.gz
```

Use the URL `http://localhost:3721/` in a browser to view reports and charts. Alternatively, you can use the in-memory mode without persisting data, for example:
Use the URL `http://localhost:3721/` in a browser to view reports and charts. Alternatively, you can use the *in-memory* mode without persisting data, for example:
```bash
./dist/hatchet -in-memory mongod.log.gz
./dist/hatchet -url in-memory mongod.log.gz
```

Using MongoDB as the database is also supported. The example below stores data in collections under *hatchet* database.
```bash
./dist/hatchet -url mongodb+srv://{user}:{password}@localhost/hatchet mongod.log.gz
```

if you choose to view in the legacy format without a browser, use the command below:
Expand Down
4 changes: 3 additions & 1 deletion README_DEV.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ The Hatchet provides many flexible ways to access data. After processing logs,
- Access data directly in applications using SQLite3 API
- Output data from the SQLite3 database to a TSV file to be used in a spreadsheet
- Output the legacy-formatted logs to a file for other tools
- Can serve as a RESTful to check drivers compatibility
- Supported databases are SQLite3 and MongoDB (with `-url {URL}`)

Note that there are a few indexes created during the logs processings But, you may create additional indexes to support additional needs.

Expand Down Expand Up @@ -63,7 +65,7 @@ SELECT date, severity, message FROM mongod_1b3d5f7 WHERE component = 'NETWORK';
### Query Ops Stats
```sqlite3
SELECT op, COUNT(*) "count", ROUND(AVG(milli),1) avg_ms, MAX(milli) max_ms, SUM(milli) total_ms,
ns, _index "index", SUM(reslen) "reslen", filter "query pattern"
ns, _index "index", SUM(reslen) "reslen", filter "query_pattern"
FROM mongod_1b3d5f7
WHERE op != "" GROUP BY op, ns, filter ORDER BY avg_ms DESC;
```
Expand Down
10 changes: 5 additions & 5 deletions database.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
package hatchet

type NameValue struct {
Name string
Value int
Name string `bson:"name"`
Value int `bson:"value"`
}

type NameValues struct {
Expand All @@ -24,12 +24,9 @@ type Database interface {
GetAcceptedConnsCounts(duration string) ([]NameValue, error)
GetAuditData() (map[string][]NameValues, error)
GetAverageOpTime(op string, duration string) ([]OpCount, error)
GetClientPreparedStmt() string
GetConnectionStats(chartType string, duration string) ([]RemoteClient, error)
GetHatchetInfo() HatchetInfo
GetHatchetInitStmt() string
GetHatchetNames() ([]string, error)
GetHatchetPreparedStmt() string
GetLogs(opts ...string) ([]LegacyLog, error)
GetOpsCounts(duration string) ([]NameValue, error)
GetReslenByNamespace(ip string, duration string) ([]NameValue, error)
Expand All @@ -46,5 +43,8 @@ type Database interface {
}

func GetDatabase(hatchetName string) (Database, error) {
if GetLogv2().GetDBType() == Mongo {
return GetMongoDB(hatchetName)
}
return GetSQLite3DB(hatchetName)
}
16 changes: 14 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,20 @@ require (
github.com/julienschmidt/httprouter v1.3.0
github.com/mattn/go-sqlite3 v1.14.16
github.com/simagix/gox v0.2.3
go.mongodb.org/mongo-driver v1.11.2
go.mongodb.org/mongo-driver v1.11.3
golang.org/x/text v0.7.0
)

require github.com/jmespath/go-jmespath v0.4.0 // indirect
require (
github.com/golang/snappy v0.0.1 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/klauspost/compress v1.13.6 // indirect
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
github.com/xdg-go/scram v1.1.1 // indirect
github.com/xdg-go/stringprep v1.0.3 // indirect
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d // indirect
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect
)
17 changes: 15 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ github.com/aws/aws-sdk-go v1.44.219/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
Expand All @@ -12,13 +13,18 @@ github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGw
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U=
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc=
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe h1:iruDEfMl2E6fbMZ9s0scYfZQ84/6SPL6zC8ACM2oIL0=
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
Expand All @@ -29,15 +35,20 @@ github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
github.com/xdg-go/scram v1.1.1 h1:VOMT+81stJgXW3CpHyqHN3AXDYIMsx56mEFrB37Mb/E=
github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g=
github.com/xdg-go/stringprep v1.0.3 h1:kdwGpVNwPFtjs98xCGkHjQtGKh86rDcRZN17QEMCOIs=
github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8=
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA=
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.mongodb.org/mongo-driver v1.11.2 h1:+1v2rDQUWNcGW7/7E0Jvdz51V38XXxJfhzbV17aNHCw=
go.mongodb.org/mongo-driver v1.11.2/go.mod h1:s7p5vEtfbeR1gYi6pnj3c3/urpbLv2T5Sfd6Rp2HBB8=
go.mongodb.org/mongo-driver v1.11.3 h1:Ql6K6qYHEzB6xvu4+AU0BoRoqf9vFPcc4o7MUIdPW8Y=
go.mongodb.org/mongo-driver v1.11.3/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5quethTUn9WM+2g=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d h1:sK3txAijHtOK88l68nt020reeT1ZdKLIYetKl95FzVY=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
Expand All @@ -48,6 +59,7 @@ golang.org/x/net v0.1.0 h1:hZ/3BUoy5aId7sCpA/Tc5lt8DkFgdVS2onTpJsZ/fl0=
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
Expand All @@ -70,6 +82,7 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Expand Down
56 changes: 33 additions & 23 deletions hatchet.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"net"
"net/http"
"regexp"
"strings"

"github.com/julienschmidt/httprouter"
"github.com/mattn/go-sqlite3"
Expand All @@ -22,14 +23,14 @@ import (
const SQLITE3_FILE = "./data/hatchet.db"

func Run(fullVersion string) {
dbfile := flag.String("dbfile", SQLITE3_FILE, "database file name")
dbfile := flag.String("dbfile", SQLITE3_FILE, "deprecated, use -url")
digest := flag.Bool("digest", false, "HTTP digest")
endpoint := flag.String("endpoint-url", "", "AWS endpoint")
inMem := flag.Bool("in-memory", false, "use in-memory mode")
legacy := flag.Bool("legacy", false, "view logs in legacy format")
port := flag.Int("port", 3721, "web server port number")
profile := flag.String("aws-profile", "default", "AWS profile name")
s3 := flag.Bool("s3", false, "files from AWS S3")
connstr := flag.String("url", SQLITE3_FILE, "database file name or connection string")
user := flag.String("user", "", "HTTP Auth (username:password)")
ver := flag.Bool("version", false, "print version number")
verbose := flag.Bool("verbose", false, "turn on verbose")
Expand All @@ -45,38 +46,50 @@ func Run(fullVersion string) {
if !*legacy {
log.Println(fullVersion)
}
if *connstr == "" {
connstr = dbfile
}

if *inMem {
if *dbfile != SQLITE3_FILE {
log.Fatalln("cannot use -dbfile and -in-memory together")
} else if len(flag.Args()) == 0 {
if *connstr == "in-memory" {
if len(flag.Args()) == 0 {
log.Fatalln("cannot use -in-memory without a log file")
}
log.Println("in-memory mode is enabled, no data will be persisted")
*dbfile = "file::memory:?cache=shared"
*connstr = "file::memory:?cache=shared"
*web = true
}

regex := func(re, s string) (bool, error) {
return regexp.MatchString(re, s)
logv2 := Logv2{version: fullVersion, url: *connstr, verbose: *verbose,
legacy: *legacy, user: *user, isDigest: *digest}
instance = &logv2
str := *connstr
if strings.HasPrefix(*connstr, "mongodb") {
pattern := regexp.MustCompile(`mongodb(\+srv)?:\/\/(.+):(.+)@(.+)`)
matches := pattern.FindStringSubmatch(str)
if matches != nil {
str = fmt.Sprintf("mongodb%s://%s@%s", matches[1], matches[2], matches[4])
}
}
log.Println("using database", str)
if GetLogv2().GetDBType() == SQLite3 {
regex := func(re, s string) (bool, error) {
return regexp.MatchString(re, s)
}
sql.Register("sqlite3_extended",
&sqlite3.SQLiteDriver{
ConnectHook: func(conn *sqlite3.SQLiteConn) error {
return conn.RegisterFunc("regexp", regex, true)
},
})
}
sql.Register("sqlite3_extended",
&sqlite3.SQLiteDriver{
ConnectHook: func(conn *sqlite3.SQLiteConn) error {
return conn.RegisterFunc("regexp", regex, true)
},
})
logv2 := Logv2{version: fullVersion, dbfile: *dbfile, verbose: *verbose, legacy: *legacy, user: *user, isDigest: *digest}
if *s3 {
var err error
if logv2.s3client, err = NewS3Client(*profile, *endpoint); err != nil {
log.Fatal(err)
}
}
instance = &logv2
for _, filename := range flag.Args() {
err := logv2.Analyze(filename)
if err != nil {
for _, logname := range flag.Args() {
if err := logv2.Analyze(logname); err != nil {
log.Fatal(err)
}
}
Expand All @@ -103,9 +116,6 @@ func Run(fullVersion string) {
log.Fatal(err)
} else {
listener.Close()
if !*inMem {
log.Println("using data file", *dbfile)
}
log.Println("starting web server at", addr)
log.Fatal(http.ListenAndServe(addr, router))
}
Expand Down
Loading