slowquery

package
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 17, 2026 License: Apache-2.0 Imports: 4 Imported by: 0

Documentation

Overview

Package slowquery parses Postgres and MySQL slow-query log lines into structured entries with a timestamp, duration, and query text.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Entry

type Entry struct {
	Timestamp time.Time
	// DurationMs is the statement's own reported execution time in
	// milliseconds (Postgres' "duration:", MySQL's "Query_time"
	// converted from seconds).
	DurationMs float64
	Query      string
	// RowsExamined is 0 when the engine's slow query log doesn't report
	// it (Postgres never does; MySQL always does for a real slow-log
	// entry).
	RowsExamined int64
}

Entry is one parsed slow query.

func ParseMySQL

func ParseMySQL(lines []LogLine) []Entry

ParseMySQL extracts every slow-query entry from lines, in the order given, reconstructing each entry's multi-line block: a "# Query_time:" header, an optional "# User@Host:"/"SET timestamp=...;" line, then one or more lines of SQL text terminated by the next header line (another "#"-prefixed line) or the end of input. Everything before the first header line, and any "#"-prefixed line that isn't a header this package recognizes (e.g. "# Time:", "# User@Host:"), is skipped.

Example
package main

import (
	"fmt"
	"time"

	"github.com/GLINCKER/levelrail/kit/slowquery"
)

func main() {
	now := time.Date(2026, 1, 1, 0, 0, 0, 0, time.UTC)
	lines := []slowquery.LogLine{
		{Timestamp: now, Message: "# Query_time: 2.500000  Lock_time: 0.000100 Rows_sent: 1  Rows_examined: 90000"},
		{Timestamp: now, Message: "SELECT COUNT(*) FROM events;"},
	}
	for _, e := range slowquery.ParseMySQL(lines) {
		fmt.Printf("%.0f ms, %d rows examined: %s\n", e.DurationMs, e.RowsExamined, e.Query)
	}
}
Output:
2500 ms, 90000 rows examined: SELECT COUNT(*) FROM events

func ParsePostgres

func ParsePostgres(lines []LogLine) []Entry

ParsePostgres extracts every slow-statement entry from lines, in the order given. Non-matching lines (ordinary Postgres log output that isn't a duration line) are skipped, not treated as an error: the raw log stream mixes slow-query lines with every other message Postgres writes to stderr.

Example
package main

import (
	"fmt"
	"time"

	"github.com/GLINCKER/levelrail/kit/slowquery"
)

func main() {
	now := time.Date(2026, 1, 1, 0, 0, 0, 0, time.UTC)
	lines := []slowquery.LogLine{
		{Timestamp: now, Message: "2026-01-01 00:00:00 UTC [41] LOG:  checkpoint starting: time"},
		{Timestamp: now, Message: "2026-01-01 00:00:01 UTC [42] LOG:  duration: 1532.411 ms  statement: SELECT * FROM orders WHERE status = 'open'"},
	}
	for _, e := range slowquery.ParsePostgres(lines) {
		fmt.Printf("%.0f ms: %s\n", e.DurationMs, e.Query)
	}
}
Output:
1532 ms: SELECT * FROM orders WHERE status = 'open'

type LogLine

type LogLine struct {
	Timestamp time.Time
	Message   string
}

LogLine is one stored container log line: its own capture timestamp (not the engine's in-message timestamp text) and raw message.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL