Skip to content

Commit

Permalink
MEDIUM: Add support for the log-profile section
Browse files Browse the repository at this point in the history
  • Loading branch information
oliwer committed Feb 3, 2025
1 parent cb5c274 commit 389b6b5
Show file tree
Hide file tree
Showing 49 changed files with 2,970 additions and 3 deletions.
2 changes: 2 additions & 0 deletions config-parser/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ type ConfiguredParsers struct {
FCGIApp *Parsers
CrtStore *Parsers
Traces *Parsers
LogProfile *Parsers
// spoe parsers
SPOEAgent *Parsers
SPOEGroup *Parsers
Expand Down Expand Up @@ -97,4 +98,5 @@ func (p *configParser) initParserMaps() {
p.Parsers[FCGIApp] = map[string]*Parsers{}
p.Parsers[CrtStore] = map[string]*Parsers{}
p.Parsers[Traces] = map[string]*Parsers{}
p.Parsers[LogProfile] = map[string]*Parsers{}
}
1 change: 1 addition & 0 deletions config-parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ const (
FCGIApp Section = "fcgi-app"
CrtStore Section = "crt-store"
Traces Section = "traces"
LogProfile Section = "log-profile"
// spoe sections
SPOEAgent Section = "spoe-agent"
SPOEGroup Section = "spoe-group"
Expand Down
13 changes: 13 additions & 0 deletions config-parser/parsers/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ func (l *Log) Init() {
l.preComments = []string{}
}

//nolint:gocognit
func (l *Log) parse(line string, parts []string, comment string) (*types.Log, error) {
if len(parts) > 1 && parts[1] == "global" {
return &types.Log{
Expand Down Expand Up @@ -113,6 +114,14 @@ func (l *Log) parse(line string, parts []string, comment string) (*types.Log, er
}
currIndex++
}
if currIndex < len(parts) && parts[currIndex] == "profile" {
currIndex++
if currIndex >= len(parts) {
return log, &errors.ParseError{Parser: "Log", Line: line}
}
log.Profile = parts[currIndex]
currIndex++
}
// we must have facility
if currIndex >= len(parts) {
return log, &errors.ParseError{Parser: "Log", Line: line}
Expand Down Expand Up @@ -201,6 +210,10 @@ func (l *Log) Result() ([]common.ReturnResultLine, error) {
sb.WriteString(":")
sb.WriteString(strconv.FormatInt(log.SampleSize, 10))
}
if log.Profile != "" {
sb.WriteString(" profile ")
sb.WriteString(log.Profile)
}
sb.WriteString(" ")
sb.WriteString(log.Facility)
if log.Level != "" {
Expand Down
138 changes: 138 additions & 0 deletions config-parser/parsers/on-log-step.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
/*
Copyright 2025 HAProxy Technologies
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package parsers

import (
"slices"

"github.com/haproxytech/client-native/v6/config-parser/common"
"github.com/haproxytech/client-native/v6/config-parser/errors"
"github.com/haproxytech/client-native/v6/config-parser/types"
)

type OnLogStep struct {
data []types.OnLogStep
preComments []string // comments that appear before the actual line
}

func (o *OnLogStep) GetParserName() string {
return "on"
}

func (o *OnLogStep) Parse(line string, parts []string, comment string) (string, error) {
if parts[0] == o.GetParserName() {
data, err := o.parse(line, parts, comment)
if err != nil {
if _, ok := err.(*errors.ParseError); ok { //nolint:errorlint
return "", err
}
return "", &errors.ParseError{Parser: "OnLogStep", Line: line}
}
o.data = append(o.data, *data)
return "", nil
}
return "", &errors.ParseError{Parser: "OnLogStep", Line: line}
}

func (o *OnLogStep) parse(line string, parts []string, comment string) (*types.OnLogStep, error) {
on := o.GetParserName()
if parts[0] != on {
return nil, &errors.ParseError{Parser: on, Line: line}
}
if len(parts) < 3 {
return nil, &errors.ParseError{Parser: on, Line: line, Message: "Parse error: not enough arguments"}
}

var step types.OnLogStep
step.Comment = comment

step.Step = parts[1]
if !o.isKnownStep(step.Step) {
return nil, &errors.ParseError{Parser: on, Line: line, Message: "Parse error: invalid step name"}
}

if parts[2] == "drop" {
if len(parts) > 3 {
return nil, &errors.ParseError{Parser: on, Line: line, Message: "Parse error: nothing is allowed after 'drop'"}
}
step.Drop = true
return &step, nil
}

parts = parts[2:]

if len(parts) < 2 {
return nil, &errors.ParseError{Parser: on, Line: line, Message: "Parse error: not enough arguments"}
}

for {
switch parts[0] {
case "format":
step.Format = parts[1]
case "sd":
step.Sd = parts[1]
default:
return nil, &errors.ParseError{Parser: on, Line: line, Message: "Parse error: bad trailing argument"}
}
if len(parts) == 2 {
break // success
}
if len(parts) > 2 {
parts = parts[2:]
} else {
return nil, &errors.ParseError{Parser: on, Line: line, Message: "Parse error: bad trailing argument"}
}
}

return &step, nil
}

func (o *OnLogStep) Result() ([]common.ReturnResultLine, error) {
if len(o.data) == 0 {
return nil, errors.ErrFetch
}

result := make([]common.ReturnResultLine, len(o.data))
on := o.GetParserName()

for i, step := range o.data {
if step.Drop {
result[i] = common.ReturnResultLine{
Data: common.SmartJoin(on, step.Step, "drop"),
Comment: step.Comment,
}
continue
}
result[i] = common.ReturnResultLine{
Data: common.SmartJoin(on, step.Step,
o.maybe("format", step.Format), step.Format,
o.maybe("sd", step.Sd), step.Sd),
Comment: step.Comment,
}
}
return result, nil
}

func (o *OnLogStep) maybe(keyword, value string) string {
if len(value) > 0 {
return keyword
}
return ""
}

func (o *OnLogStep) isKnownStep(step string) bool {
return slices.Contains([]string{"accept", "any", "close", "connect", "error", "request", "response", "http-req", "http-res", "http-after-res", "quic-init", "tcp-req-conn", "tcp-req-cont", "tcp-req-sess"}, step)
}
138 changes: 138 additions & 0 deletions config-parser/parsers/on-log-step_generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions config-parser/reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,16 @@ func (p *configParser) ProcessLine(line string, parts []string, comment string,
}
}
config.Active = config.Traces
case "log-profile":
parserSectionName := parser.(*extra.Section) //nolint:forcetypeassert
rawData, _ := parserSectionName.Get(false)
data := rawData.(*types.Section) //nolint:forcetypeassert
config.LogProfile = p.getLogProfileParser()
p.Parsers[LogProfile][data.Name] = config.LogProfile
config.Active = config.LogProfile
if p.Options.Log {
p.Options.Logger.Tracef("%slog-profile section %s active", p.Options.LogPrefix, data.Name)
}
case "snippet_beg":
config.Previous = config.Active
config.Active = &Parsers{
Expand Down
9 changes: 9 additions & 0 deletions config-parser/section-parsers.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ func (p *configParser) createParsers(parser map[string]ParserInterface, sequence
addParser(parser, &sequence, &extra.Section{Name: "fcgi-app"})
addParser(parser, &sequence, &extra.Section{Name: "crt-store"})
addParser(parser, &sequence, &extra.Section{Name: "traces"})
addParser(parser, &sequence, &extra.Section{Name: "log-profile"})
if !p.Options.DisableUnProcessed {
addParser(parser, &sequence, &extra.UnProcessed{})
}
Expand Down Expand Up @@ -986,3 +987,11 @@ func (p *configParser) getTracesParser() *Parsers {
addParser(parser, &sequence, &parsers.Trace{})
return p.createParsers(parser, sequence)
}

func (p *configParser) getLogProfileParser() *Parsers {
parser := map[string]ParserInterface{}
sequence := []Section{}
addParser(parser, &sequence, &simple.Word{Name: "log-tag"})
addParser(parser, &sequence, &parsers.OnLogStep{})
return p.createParsers(parser, sequence)
}
Loading

0 comments on commit 389b6b5

Please sign in to comment.