Skip to content

Commit

Permalink
removed driver dependency
Browse files Browse the repository at this point in the history
  • Loading branch information
nidorx committed Oct 11, 2024
1 parent e89ac27 commit f63ca7f
Show file tree
Hide file tree
Showing 20 changed files with 816 additions and 203 deletions.
17 changes: 11 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,6 @@

**SQLog** is a **Golang** library that simplifies log management using **slog**. **SQLog** offers a lightweight and reliable solution for logging, making it perfect for developers seeking a cost-effective, high-performance way to monitor their applications.

It integrates with **SQLite**, so no external database setup is required. This keeps operations simple and reduces costs, as everything runs **embedded**.



## Usage

Below is an example of using **SQLog** with the SQLite storage, with the interface exposed on port `8080`. When you access `http://localhost:8080?msg=test`, any query parameter will be sent to the log.
Expand All @@ -39,7 +35,12 @@ import (
"strings"

"github.com/nidorx/sqlog"

// sqlite storage
"github.com/nidorx/sqlog/sqlite"

// sqlite driver
_ "github.com/mattn/go-sqlite3"
)

func main() {
Expand Down Expand Up @@ -141,9 +142,13 @@ The combination of these layers makes **SQLog** a robust and efficient solution

## Requirements

The builtin SQLite storage uses the package `github.com/mattn/go-sqlite3`, which is a cgo package, so you need `gcc`.
To use the builtin SQLite Storage implementation, you need to register the driver of your choice.

Examples:

- `github.com/mattn/go-sqlite3`
- `modernc.org/sqlite`

See the link for more details: [https://github.com/mattn/go-sqlite3?tab=readme-ov-file#installation](https://github.com/mattn/go-sqlite3?tab=readme-ov-file#installation)

## @TODO/IDEAS/ROADMAP

Expand Down
5 changes: 5 additions & 0 deletions chunk.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ func (c *Chunk) Size() int64 {
return atomic.LoadInt64(&c.size)
}

// Size returns the number of flush retries for this chunk
func (c *Chunk) Retries() int32 {
return atomic.LoadInt32(&c.retries)
}

// Init initializes the next chunks
func (c *Chunk) Init(depth uint8) {
if depth > 0 {
Expand Down
7 changes: 5 additions & 2 deletions demo/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,20 @@ FROM golang:1.23.2-alpine AS builder
# smoke test to verify if golang is available
RUN go version

RUN apk --no-cache add gcc g++ sqlite
RUN apk --no-cache add gcc g++

ARG GO_TAGS
ARG PROJECT_VERSION

WORKDIR /go/src/demo/
COPY . ./
COPY go.mod.txt ./go.mod
COPY driver-mattn.go.txt ./driver-mattn.go
COPY driver-modernc.go.txt ./driver-modernc.go

RUN set -Eeux && go mod tidy && go mod download && go mod verify

RUN GOOS=linux CGO_ENABLED=1 go build -trimpath -ldflags="-w -s -X 'main.Version=${PROJECT_VERSION}'" -o app main.go
RUN GOOS=linux CGO_ENABLED=1 go build -tags $GO_TAGS -trimpath -ldflags="-w -s -X 'main.Version=${PROJECT_VERSION}'" -o app main.go

# Stage 2
FROM alpine:3.20.3
Expand Down
5 changes: 4 additions & 1 deletion demo/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,11 @@ The demo project captures all mouse movements and sends them to the server, whic

## Build Docker (To deploy on render.com)

- **GO_TAGS=mattn**: Use github.com/mattn/go-sqlite3 driver
- **GO_TAGS=modernc**: Use modernc.org/sqlite driver

```
docker build --build-arg PROJECT_VERSION=1.0.0 -t nidorx/sqlog-demo:latest .
docker build --build-arg PROJECT_VERSION=1.0.0 --build-arg GO_TAGS=mattn -t nidorx/sqlog-demo:latest .
# run
docker run -p 8080:8080 nidorx/sqlog-demo:latest
Expand Down
8 changes: 8 additions & 0 deletions demo/driver-mattn.go.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//go:build mattn
// +build mattn

package main

import (
_ "github.com/mattn/go-sqlite3"
)
8 changes: 8 additions & 0 deletions demo/driver-modernc.go.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//go:build modernc
// +build modernc

package main

import (
_ "modernc.org/sqlite"
)
6 changes: 4 additions & 2 deletions demo/go.mod.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ go 1.23

toolchain go1.23.1

require (
github.com/nidorx/sqlog v0.0.6
require (
github.com/nidorx/sqlog v0.0.7
modernc.org/sqlite v1.33.1
github.com/mattn/go-sqlite3 v1.14.24
)

2 changes: 1 addition & 1 deletion demo/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func init() {
Dir: "logs",
Prefix: "demo",
MaxFilesizeMB: 10,
TotalSizeCapMB: 100,
MaxSizeTotalMB: 100,
MaxOpenedDB: 2,
MaxRunningTasks: 5,
CloseIdleSec: 10,
Expand Down
1 change: 0 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ go 1.23
toolchain go1.23.1

require (
github.com/mattn/go-sqlite3 v1.14.23
github.com/pmezard/go-difflib v1.0.0
github.com/stretchr/testify v1.9.0
)
Expand Down
2 changes: 0 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
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/mattn/go-sqlite3 v1.14.23 h1:gbShiuAP1W5j9UOksQ06aiiqPMxYecovVGwmTxWtuw0=
github.com/mattn/go-sqlite3 v1.14.23/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
Expand Down
6 changes: 3 additions & 3 deletions ingester_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,10 +130,10 @@ func Test_Ingester_MaxFlushRetry(t *testing.T) {
waitMax(5*time.Second, func() bool {
mu.Lock()
defer mu.Unlock()
return (chunk != nil && atomic.LoadInt32(&chunk.retries) > 1)
return (chunk != nil && chunk.Retries() > 1)
})

assert.Equal(t, int32(2), atomic.LoadInt32(&chunk.retries))
assert.Equal(t, int32(2), chunk.Retries())
}

func Test_Ingester_MaxDirtyChunks(t *testing.T) {
Expand Down Expand Up @@ -248,7 +248,7 @@ func Test_Ingester_Close_MaxFlushRetry(t *testing.T) {
assert.NoError(t, err)

assert.True(t, closed, "Storage.Close not called")
assert.Equal(t, int32(2), atomic.LoadInt32(&chunk.retries))
assert.Equal(t, int32(2), chunk.Retries())
}

func waitMax(max time.Duration, condition func() bool) {
Expand Down
18 changes: 13 additions & 5 deletions sqlite/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@ import (
"errors"
"strings"
"sync"
"sync/atomic"
"time"

"github.com/nidorx/sqlog"

_ "github.com/mattn/go-sqlite3"
)

type Config struct {
Expand All @@ -33,7 +32,7 @@ type Config struct {
// The total size of all archived files. Once this cap is exceeded,
// the oldest archive files will be deleted asynchronously.
// (Default: 1000MB).
TotalSizeCapMB int32
MaxSizeTotalMB int32

// The maximum number of databases that can be opened simultaneously.
MaxOpenedDB int32
Expand Down Expand Up @@ -79,6 +78,7 @@ type storage struct {
taskIdSeq int32 // Last task ID
taskMap sync.Map // Stores task execution outputs
numActiveTasks int32 // Tracks the number of active goroutines for scheduled tasks
closed atomic.Bool
quit chan struct{}
shutdown chan struct{}
}
Expand Down Expand Up @@ -108,8 +108,8 @@ func New(config *Config) (*storage, error) {
config.MaxFilesizeMB = 20 // ~20MB
}

if config.TotalSizeCapMB <= 0 {
config.TotalSizeCapMB = 1000 // ~1GB
if config.MaxSizeTotalMB <= 0 {
config.MaxSizeTotalMB = 1000 // ~1GB
}

if config.IntervalScheduledTasksMs <= 0 {
Expand Down Expand Up @@ -204,8 +204,16 @@ func (s *storage) Flush(chunk *sqlog.Chunk) error {

// Close closes all databases and cleans up.
func (s *storage) Close() error {

// stop routines
close(s.quit)
<-s.shutdown

// close dbs
for _, db := range s.dbs {
db.close()
}

s.closed.Store(true)
return nil
}
Loading

0 comments on commit f63ca7f

Please sign in to comment.