2022-11-06 14:33:57 +00:00
|
|
|
package logmower
|
|
|
|
|
|
|
|
import (
|
2022-11-06 14:52:22 +00:00
|
|
|
"context"
|
2022-11-06 14:33:57 +00:00
|
|
|
"time"
|
|
|
|
|
|
|
|
"go.mongodb.org/mongo-driver/bson"
|
2022-11-06 14:52:22 +00:00
|
|
|
"go.mongodb.org/mongo-driver/mongo"
|
2022-11-06 14:33:57 +00:00
|
|
|
)
|
|
|
|
|
2022-11-06 14:52:22 +00:00
|
|
|
func initializeIndexes(ctx context.Context, col *mongo.Collection) error {
|
|
|
|
ind := col.Indexes()
|
|
|
|
|
|
|
|
// (does not create duplicates)
|
|
|
|
_, err := ind.CreateOne(mongoTimeoutCtx(ctx), mongo.IndexModel{
|
2022-11-06 21:15:23 +00:00
|
|
|
Keys: bson.D{{Key: mLogKeyFileBasename, Value: 1}, {Key: mLogKeyOffset, Value: -1}},
|
2022-11-06 14:52:22 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2022-11-06 14:33:57 +00:00
|
|
|
// when editing, also edit everything in this file!
|
2022-11-06 20:02:29 +00:00
|
|
|
type (
|
|
|
|
mLog struct {
|
2022-11-06 21:15:23 +00:00
|
|
|
RecordMetadata
|
2022-11-06 20:02:29 +00:00
|
|
|
|
|
|
|
Content any
|
|
|
|
ContainerTime time.Time
|
|
|
|
StdErr bool
|
|
|
|
|
|
|
|
// added by toBson()
|
|
|
|
ShipTime time.Time
|
|
|
|
}
|
2022-11-06 21:15:23 +00:00
|
|
|
RecordMetadata struct {
|
2022-11-06 20:02:29 +00:00
|
|
|
HostInfo HostInfo
|
|
|
|
File string
|
|
|
|
Offset int64 // byte offset where log entry ends at
|
|
|
|
}
|
|
|
|
)
|
2022-11-06 14:33:57 +00:00
|
|
|
|
|
|
|
const (
|
2022-11-06 21:15:23 +00:00
|
|
|
// used outside fromBson and toBson
|
|
|
|
mLogKeyHostId = mLogKeyHostInfo + "." + mLogKeyId
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
mLogKeyHostInfo = "host_info"
|
|
|
|
mLogKeyId = "id"
|
|
|
|
mLogKeyName = "name"
|
|
|
|
mLogKeyArch = "arch"
|
|
|
|
|
|
|
|
mLogKeyFileBasename = "file"
|
|
|
|
mLogKeyOffset = "offset"
|
|
|
|
mLogKeyContent = "content"
|
|
|
|
mLogKeyContainerTime = "container_time"
|
|
|
|
mLogKeyStderr = "stderr"
|
|
|
|
mLogKeyShipTime = "ship_time"
|
2022-11-06 14:33:57 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// not using marshal, since it is <0.1x performance
|
|
|
|
func (l *mLog) toBson() bson.M {
|
|
|
|
// DO NOT USE QUOTED STRINGS! Move them to const and use variable instead
|
|
|
|
return bson.M{
|
2022-11-06 21:15:23 +00:00
|
|
|
mLogKeyHostInfo: bson.M{
|
|
|
|
mLogKeyId: l.HostInfo.Id,
|
|
|
|
mLogKeyName: l.HostInfo.Name,
|
|
|
|
mLogKeyArch: l.HostInfo.Arch,
|
2022-11-06 14:33:57 +00:00
|
|
|
},
|
2022-11-06 21:15:23 +00:00
|
|
|
mLogKeyFileBasename: l.File,
|
|
|
|
mLogKeyOffset: l.Offset,
|
|
|
|
mLogKeyContent: l.Content,
|
|
|
|
mLogKeyContainerTime: l.ContainerTime,
|
|
|
|
mLogKeyStderr: l.StdErr,
|
2022-11-06 20:02:29 +00:00
|
|
|
|
2022-11-06 21:15:23 +00:00
|
|
|
mLogKeyShipTime: time.Now(),
|
2022-11-06 14:33:57 +00:00
|
|
|
}
|
|
|
|
}
|
2022-11-06 21:15:23 +00:00
|
|
|
|
|
|
|
// really, mongo should support tagged structs
|
|
|
|
func mLogfromBson(b *bson.Raw) mLog {
|
|
|
|
return mLog{
|
|
|
|
RecordMetadata: RecordMetadata{
|
|
|
|
HostInfo: HostInfo{
|
|
|
|
Id: bsonLookupStringValue(b, mLogKeyHostInfo, mLogKeyId),
|
|
|
|
Name: bsonLookupStringValue(b, mLogKeyHostInfo, mLogKeyName),
|
|
|
|
Arch: bsonLookupStringValue(b, mLogKeyHostInfo, mLogKeyArch),
|
|
|
|
},
|
|
|
|
File: bsonLookupStringValue(b, mLogKeyFileBasename),
|
|
|
|
Offset: bsonLookupInt64(b, mLogKeyOffset),
|
|
|
|
},
|
|
|
|
Content: bsonLookupStringValue(b, mLogKeyContent),
|
|
|
|
ContainerTime: bsonLookupTime(b, mLogKeyContainerTime),
|
|
|
|
StdErr: bsonLookupBoolean(b, mLogKeyStderr),
|
|
|
|
ShipTime: bsonLookupTime(b, mLogKeyShipTime),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// default values without ok
|
|
|
|
|
|
|
|
func bsonLookupBoolean(b *bson.Raw, key ...string) bool {
|
|
|
|
v, _ := b.Lookup(key...).BooleanOK()
|
|
|
|
return v
|
|
|
|
}
|
|
|
|
|
|
|
|
func bsonLookupStringValue(b *bson.Raw, key ...string) string {
|
|
|
|
v, _ := b.Lookup(key...).StringValueOK()
|
|
|
|
return v
|
|
|
|
}
|
|
|
|
|
|
|
|
func bsonLookupInt64(b *bson.Raw, key ...string) int64 {
|
|
|
|
v, _ := b.Lookup(key...).Int64OK()
|
|
|
|
return v
|
|
|
|
}
|
|
|
|
|
|
|
|
func bsonLookupTime(b *bson.Raw, key ...string) time.Time {
|
|
|
|
v, _ := b.Lookup(key...).TimeOK()
|
|
|
|
return v
|
|
|
|
}
|