Brijesh's Git Server — argus-core @ ad14ae9ef6df214964267107a8b29d85545baddb

Logging service

fix: changes for use with client
Brijesh Wawdhane ops@brijesh.dev
Fri, 27 Dec 2024 19:20:45 +0530
commit

ad14ae9ef6df214964267107a8b29d85545baddb

parent

979f64deddba73493e6ef65581a166b4b7ecd9c3

M MakefileMakefile

@@ -1,7 +1,4 @@

build: - @echo "Building..." - - @go build -o main cmd/api/main.go run:
M db.cqldb.cql

@@ -39,3 +39,11 @@ log_level text,

message text, PRIMARY KEY ((application_id), timestamp, log_id) ) WITH CLUSTERING ORDER BY (timestamp DESC); + +CREATE TABLE IF NOT EXISTS argus.log_frequencies ( + application_id uuid, + interval_start timestamp, -- The start time of the interval + interval_end timestamp, -- The end time of the interval + log_count int, -- Count of logs in that time interval + PRIMARY KEY ((application_id), interval_start) +) WITH CLUSTERING ORDER BY (interval_start DESC);
M deployment.yamldeployment.yaml

@@ -16,7 +16,7 @@ app: argus-core

spec: containers: - name: argus-core - image: brijeshwawdhane/argus-core:0.1.0-alpha.7 + image: brijeshwawdhane/argus-core:0.1.1-alpha.1 ports: - containerPort: 8080 envFrom:
M internal/applications/validation.gointernal/applications/validation.go

@@ -1,35 +1,36 @@

package applications import ( - pb "argus-core/rpc/applications" "fmt" + + pb "argus-core/rpc/applications" ) func validateCreateApplicationRequest(req *pb.CreateApplicationRequest) error { - if req.Name == "" { - return fmt.Errorf("name is required") - } - if len(req.Name) > 255 { - return fmt.Errorf("name must be less than 256 characters") - } - if len(req.Description) > 1000 { - return fmt.Errorf("description must be less than 1000 characters") - } - return nil + if req.Name == "" { + return fmt.Errorf("name is required") + } + if len(req.Name) > 255 { + return fmt.Errorf("name must be less than 256 characters") + } + if len(req.Description) > 1000 { + return fmt.Errorf("description must be less than 1000 characters") + } + return nil } func validateUpdateApplicationRequest(req *pb.UpdateApplicationRequest) error { - if req.ApplicationId == "" { - return fmt.Errorf("application ID is required") - } - if req.Name == "" { - return fmt.Errorf("name is required") - } - if len(req.Name) > 255 { - return fmt.Errorf("name must be less than 256 characters") - } - if len(req.Description) > 1000 { - return fmt.Errorf("description must be less than 1000 characters") - } - return nil + if req.ApplicationId == "" { + return fmt.Errorf("application ID is required") + } + if req.Name == "" { + return fmt.Errorf("name is required") + } + if len(req.Name) > 255 { + return fmt.Errorf("name must be less than 256 characters") + } + if len(req.Description) > 1000 { + return fmt.Errorf("description must be less than 1000 characters") + } + return nil }
M internal/database/ops_application.gointernal/database/ops_application.go

@@ -19,8 +19,8 @@ UpdatedAt: time.Now(),

} if err := s.session.Query(` - INSERT INTO applications (id, user_id, name, description, key_hash, created_at, updated_at) - VALUES (?, ?, ?, ?, ?, ?, ?)`, + INSERT INTO applications (id, user_id, name, description, key_hash, created_at, updated_at) + VALUES (?, ?, ?, ?, ?, ?, ?)`, app.ID, app.UserID, app.Name, app.Description, app.KeyHash, app.CreatedAt, app.UpdatedAt, ).Exec(); err != nil { return nil, fmt.Errorf("error creating application: %w", err)

@@ -32,8 +32,8 @@

func (s *service) GetApplication(id gocql.UUID) (*Application, error) { var app Application if err := s.session.Query(` - SELECT id, user_id, name, description, key_hash, created_at, updated_at - FROM applications WHERE id = ?`, + SELECT id, user_id, name, description, key_hash, created_at, updated_at + FROM applications WHERE id = ?`, id, ).Scan( &app.ID, &app.UserID, &app.Name, &app.Description,

@@ -46,8 +46,8 @@ }

func (s *service) ListApplications(userID gocql.UUID) ([]Application, error) { iter := s.session.Query(` - SELECT id, user_id, name, description, key_hash, created_at, updated_at - FROM applications WHERE user_id = ? ALLOW FILTERING`, + SELECT id, user_id, name, description, key_hash, created_at, updated_at + FROM applications WHERE user_id = ? ALLOW FILTERING`, userID, ).Iter()

@@ -70,11 +70,11 @@

func (s *service) UpdateApplication(id gocql.UUID, name, description string) (*Application, error) { now := time.Now() if err := s.session.Query(` - UPDATE applications - SET name = ?, - description = ?, - updated_at = ? - WHERE id = ?`, + UPDATE applications + SET name = ?, + description = ?, + updated_at = ? + WHERE id = ?`, name, description, now, id, ).Exec(); err != nil { return nil, fmt.Errorf("error updating application: %w", err)

@@ -84,8 +84,17 @@ return s.GetApplication(id)

} func (s *service) DeleteApplication(id gocql.UUID) error { + // First, delete all logs associated with the application if err := s.session.Query(` - DELETE FROM applications WHERE id = ?`, + DELETE FROM logs WHERE application_id = ?`, + id, + ).Exec(); err != nil { + return fmt.Errorf("error deleting application logs: %w", err) + } + + // Then delete the application itself + if err := s.session.Query(` + DELETE FROM applications WHERE id = ?`, id, ).Exec(); err != nil { return fmt.Errorf("error deleting application: %w", err)

@@ -97,10 +106,10 @@

func (s *service) RegenerateApplicationKey(appID gocql.UUID, newKeyHash string) error { now := time.Now() if err := s.session.Query(` - UPDATE applications - SET key_hash = ?, - updated_at = ? - WHERE id = ?`, + UPDATE applications + SET key_hash = ?, + updated_at = ? + WHERE id = ?`, newKeyHash, now, appID, ).Exec(); err != nil { return fmt.Errorf("error regenerating application key: %w", err)
M internal/database/ops_logs.gointernal/database/ops_logs.go

@@ -10,7 +10,7 @@ "golang.org/x/exp/rand"

) func (s *service) BatchInsertLogs(logs []Log) error { - batch := s.session.NewBatch(gocql.LoggedBatch) + batch := s.session.NewBatch(gocql.UnloggedBatch) for _, log := range logs { batch.Query(`

@@ -206,14 +206,14 @@ }

// Add to batch batch.Query(` - INSERT INTO logs ( - application_id, - timestamp, - log_id, - user_id, - log_level, - message - ) VALUES (?, ?, ?, ?, ?, ?)`, + INSERT INTO logs ( + application_id, + timestamp, + log_id, + user_id, + log_level, + message + ) VALUES (?, ?, ?, ?, ?, ?)`, applicationID, timestamp, gocql.TimeUUID(),
M internal/database/ops_user.gointernal/database/ops_user.go

@@ -17,8 +17,8 @@ UpdatedAt: time.Now(),

} if err := s.session.Query(` - INSERT INTO users (id, email, password_hash, created_at, updated_at) - VALUES (?, ?, ?, ?, ?)`, + INSERT INTO users (id, email, password_hash, created_at, updated_at) + VALUES (?, ?, ?, ?, ?)`, user.ID, user.Email, user.PasswordHash, user.CreatedAt, user.UpdatedAt, ).Exec(); err != nil { return nil, fmt.Errorf("error creating user: %w", err)

@@ -30,8 +30,8 @@

func (s *service) GetUserByEmail(email string) (*User, error) { var user User if err := s.session.Query(` - SELECT id, email, password_hash, created_at, updated_at - FROM users WHERE email = ? ALLOW FILTERING`, + SELECT id, email, password_hash, created_at, updated_at + FROM users WHERE email = ? ALLOW FILTERING`, email, ).Scan(&user.ID, &user.Email, &user.PasswordHash, &user.CreatedAt, &user.UpdatedAt); err != nil { return nil, fmt.Errorf("user not found: %w", err)

@@ -42,8 +42,8 @@

func (s *service) GetUserByID(id gocql.UUID) (*User, error) { var user User if err := s.session.Query(` - SELECT id, email, password_hash, created_at, updated_at - FROM users WHERE id = ?`, + SELECT id, email, password_hash, created_at, updated_at + FROM users WHERE id = ?`, id, ).Scan(&user.ID, &user.Email, &user.PasswordHash, &user.CreatedAt, &user.UpdatedAt); err != nil { return nil, fmt.Errorf("user not found: %w", err)
M internal/logs/validation.gointernal/logs/validation.go

@@ -1,58 +1,59 @@

package logs import ( - pb "argus-core/rpc/logs" "fmt" "time" + + pb "argus-core/rpc/logs" ) const ( - MaxBatchSize = 1000 - MaxMessageLength = 10000 + MaxBatchSize = 1000 + MaxMessageLength = 10000 ) func validateSendLogsRequest(req *pb.SendLogsRequest) error { - if req.ApiKey == "" { - return fmt.Errorf("%w: API key is required", ErrInvalidInput) - } + if req.ApiKey == "" { + return fmt.Errorf("%w: API key is required", ErrInvalidInput) + } - if len(req.Logs) == 0 { - return fmt.Errorf("%w: no logs provided", ErrInvalidInput) - } + if len(req.Logs) == 0 { + return fmt.Errorf("%w: no logs provided", ErrInvalidInput) + } - if len(req.Logs) > MaxBatchSize { - return fmt.Errorf("%w: maximum batch size is %d", ErrTooManyLogs, MaxBatchSize) - } + if len(req.Logs) > MaxBatchSize { + return fmt.Errorf("%w: maximum batch size is %d", ErrTooManyLogs, MaxBatchSize) + } - for i, log := range req.Logs { - if log.Message == "" { - return fmt.Errorf("%w: empty message in log entry %d", ErrInvalidInput, i) - } - if len(log.Message) > MaxMessageLength { - return fmt.Errorf("%w: message too long in log entry %d", ErrInvalidInput, i) - } - if log.Level == pb.LogLevel_UNKNOWN { - return fmt.Errorf("%w: invalid log level in entry %d", ErrInvalidLogLevel, i) - } - } + for i, log := range req.Logs { + if log.Message == "" { + return fmt.Errorf("%w: empty message in log entry %d", ErrInvalidInput, i) + } + if len(log.Message) > MaxMessageLength { + return fmt.Errorf("%w: message too long in log entry %d", ErrInvalidInput, i) + } + if log.Level == pb.LogLevel_UNKNOWN { + return fmt.Errorf("%w: invalid log level in entry %d", ErrInvalidLogLevel, i) + } + } - return nil + return nil } func validateGetLogsRequest(req *pb.GetLogsRequest) error { - if req.Token == "" { - return fmt.Errorf("%w: token is required", ErrInvalidInput) - } + if req.Token == "" { + return fmt.Errorf("%w: token is required", ErrInvalidInput) + } - if req.ApplicationId == "" { - return fmt.Errorf("%w: application ID is required", ErrInvalidInput) - } + if req.ApplicationId == "" { + return fmt.Errorf("%w: application ID is required", ErrInvalidInput) + } - if req.StartTime != "" { - if _, err := time.Parse(time.RFC3339, req.StartTime); err != nil { - return fmt.Errorf("%w: invalid start time format, use RFC3339", ErrInvalidInput) - } - } + if req.StartTime != "" { + if _, err := time.Parse(time.RFC3339, req.StartTime); err != nil { + return fmt.Errorf("%w: invalid start time format, use RFC3339", ErrInvalidInput) + } + } - return nil + return nil }