func (w *Waf) SetLogLevel(lvl int) error {
	switch lvl {
	case 0:
		w.LoggerAtomicLevel.SetLevel(zapcore.FatalLevel)
	case 1:
		w.LoggerAtomicLevel.SetLevel(zapcore.PanicLevel)
	case 2:
		w.LoggerAtomicLevel.SetLevel(zapcore.ErrorLevel)
	case 3:
		w.LoggerAtomicLevel.SetLevel(zapcore.WarnLevel)
	case 4:
		w.LoggerAtomicLevel.SetLevel(zapcore.InfoLevel)
	case 5:
		w.LoggerAtomicLevel.SetLevel(zapcore.DebugLevel)
	default:
		return fmt.Errorf("invalid SecDebugLogLevel value")
	}
	return nil
}
SetLogLevel changes the debug level of the Waf instance
package coraza
import (
	"errors"
	"fmt"
	"io/fs"
	"os"
	"strconv"
	"sync"
	"time"
	"github.com/jptosso/coraza-waf/loggers"
	"github.com/jptosso/coraza-waf/persistence"
	"github.com/jptosso/coraza-waf/utils"
	"github.com/jptosso/coraza-waf/utils/geoip"
	regex "github.com/jptosso/coraza-waf/utils/regex"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
)
type Phase int
type EventSeverity int
const (
	PHASE_REQUEST_HEADERS  Phase = 1
	PHASE_REQUEST_BODY     Phase = 2
	PHASE_RESPONSE_HEADERS Phase = 3
	PHASE_RESPONSE_BODY    Phase = 4
	PHASE_LOGGING          Phase = 5
)
const (
	EventEmergency EventSeverity = 0
	EventAlert     EventSeverity = 1
	EventCritical  EventSeverity = 2
	EventError     EventSeverity = 3
	EventWarning   EventSeverity = 4
	EventNotice    EventSeverity = 5
	EventInfo      EventSeverity = 6
	EventDebug     EventSeverity = 7
)
const (
	CONN_ENGINE_OFF        = 0
	CONN_ENGINE_ON         = 1
	CONN_ENGINE_DETECTONLY = 2
	AUDIT_LOG_ENABLED  = 0
	AUDIT_LOG_DISABLED = 1
	AUDIT_LOG_RELEVANT = 2
	REQUEST_BODY_PROCESSOR_DEFAULT    = 0
	REQUEST_BODY_PROCESSOR_URLENCODED = 1
	REQUEST_BODY_PROCESSOR_XML        = 2
	REQUEST_BODY_PROCESSOR_JSON       = 3
	REQUEST_BODY_PROCESSOR_MULTIPART  = 4
	REQUEST_BODY_LIMIT_ACTION_PROCESS_PARTIAL = 0
	REQUEST_BODY_LIMIT_ACTION_REJECT          = 1
	RULE_ENGINE_ON         = 0
	RULE_ENGINE_DETECTONLY = 1
	RULE_ENGINE_OFF        = 2
)
type EventLogger interface {
	Emergency(msg string)
	Alert(msg string)
	Critical(msg string)
	Error(msg string)
	Warning(msg string)
	Notice(msg string)
	Info(msg string)
	Debug(msg string)
}
type Waf struct {
	Rules *RuleGroup
	auditLoggers []loggers.Logger
	AuditEngine int
	AuditLogParts []rune
	ContentInjection bool
	RequestBodyAccess bool
	RequestBodyLimit int64
	RequestBodyInMemoryLimit int64
	ResponseBodyAccess bool
	ResponseBodyLimit int64
	RuleEngine int
	RejectOnResponseBodyLimit bool
	RejectOnRequestBodyLimit bool
	ResponseBodyMimeTypes []string
	WebAppId string
	ComponentSignature string
	ComponentNames []string
	AuditLogRelevantStatus regex.Regexp
	GeoDb geoip.GeoDb
	AbortOnRemoteRulesFail bool
	ServerSignature string
	TmpDir string
	Persistence persistence.Persistence
	SensorId string
	DataDir string
	UploadKeepFiles         bool
	UploadFileMode          fs.FileMode
	UploadFileLimit         int
	UploadDir               string
	RequestBodyNoFilesLimit int64
	CollectionTimeout       int
	Unicode *utils.Unicode
	mux *sync.RWMutex
	RequestBodyLimitAction int
	ArgumentSeparator string
	Logger *zap.Logger
	LoggerAtomicLevel zap.AtomicLevel
	ErrorLogger EventLogger
}
func (w *Waf) NewTransaction() *Transaction {
	w.mux.RLock()
	defer w.mux.RUnlock()
	tx := &Transaction{
		Waf:                  w,
		collections:          make([]*Collection, VARIABLES_COUNT),
		Id:                   utils.RandomString(19),
		Timestamp:            time.Now().UnixNano(),
		AuditEngine:          w.AuditEngine,
		AuditLogParts:        w.AuditLogParts,
		RuleEngine:           w.RuleEngine,
		RequestBodyAccess:    true,
		RequestBodyLimit:     134217728,
		ResponseBodyAccess:   true,
		ResponseBodyLimit:    524288,
		RuleRemoveTargetById: map[int][]VariableKey{},
		RuleRemoveById:       []int{},
		StopWatches:          map[Phase]int{},
		RequestBodyBuffer:    NewBodyReader(w.TmpDir, w.RequestBodyInMemoryLimit),
		ResponseBodyBuffer:   NewBodyReader(w.TmpDir, w.RequestBodyInMemoryLimit),
	}
	for i := range tx.collections {
		tx.collections[i] = NewCollection(VariableToName(byte(i)))
	}
	for i := 0x00; i <= VARIABLE_SESSIONID; i++ {
		tx.GetCollection(byte(i)).Set("", []string{""})
	}
	txvar := tx.GetCollection(VARIABLE_TX)
	for i := 0; i <= 10; i++ {
		is := strconv.Itoa(i)
		txvar.Set(is, []string{""})
	}
	defaults := map[byte]string{
		VARIABLE_URI_PARSE_ERROR:                  "0",
		VARIABLE_FILES_COMBINED_SIZE:              "0",
		VARIABLE_URLENCODED_ERROR:                 "0",
		VARIABLE_FULL_REQUEST_LENGTH:              "0",
		VARIABLE_MULTIPART_BOUNDARY_QUOTED:        "0",
		VARIABLE_MULTIPART_BOUNDARY_WHITESPACE:    "0",
		VARIABLE_MULTIPART_CRLF_LF_LINES:          "0",
		VARIABLE_MULTIPART_DATA_AFTER:             "0",
		VARIABLE_MULTIPART_DATA_BEFORE:            "0",
		VARIABLE_MULTIPART_FILE_LIMIT_EXCEEDED:    "0",
		VARIABLE_MULTIPART_HEADER_FOLDING:         "0",
		VARIABLE_MULTIPART_INVALID_HEADER_FOLDING: "0",
		VARIABLE_MULTIPART_INVALID_PART:           "0",
		VARIABLE_MULTIPART_INVALID_QUOTING:        "0",
		VARIABLE_MULTIPART_LF_LINE:                "0",
		VARIABLE_MULTIPART_MISSING_SEMICOLON:      "0",
		VARIABLE_MULTIPART_STRICT_ERROR:           "0",
		VARIABLE_MULTIPART_UNMATCHED_BOUNDARY:     "0",
		VARIABLE_OUTBOUND_DATA_ERROR:              "0",
		VARIABLE_REQBODY_ERROR:                    "0",
		VARIABLE_REQBODY_PROCESSOR_ERROR:          "0",
		VARIABLE_REQUEST_BODY_LENGTH:              "0",
		VARIABLE_DURATION:                         "0",
		VARIABLE_UNIQUE_ID:                        tx.Id,
	}
	for v, data := range defaults {
		tx.GetCollection(v).Set("", []string{data})
	}
	w.Logger.Debug("new transaction created", zap.String("event", "NEW_TRANSACTION"), zap.String("txid", tx.Id))
	return tx
}
func (w *Waf) AddAuditLogger(engine string, args map[string]string) error {
	var l loggers.Logger
	switch engine {
	case "serial":
		l = &loggers.SerialLogger{}
	case "concurrent":
		l = &loggers.ConcurrentLogger{}
	case "syslog":
		l = &loggers.SyslogLogger{}
	default:
		return errors.New("invalid logger " + engine)
	}
	err := l.New(args)
	if err != nil {
		return err
	}
	w.auditLoggers = append(w.auditLoggers, l)
	return nil
}
func (w *Waf) AuditLoggers() []loggers.Logger {
	return w.auditLoggers
}
func NewWaf() *Waf {
	atom := zap.NewAtomicLevel()
	atom.SetLevel(zap.InfoLevel)
	encoderCfg := zap.NewProductionEncoderConfig()
	logger := zap.New(zapcore.NewCore(
		zapcore.NewJSONEncoder(encoderCfg),
		zapcore.Lock(os.Stdout),
		atom,
	))
	waf := &Waf{
		ArgumentSeparator:        "&",
		AuditEngine:              AUDIT_LOG_DISABLED,
		AuditLogParts:            []rune("ABCFHZ"),
		auditLoggers:             []loggers.Logger{},
		mux:                      &sync.RWMutex{},
		RequestBodyInMemoryLimit: 131072,
		RequestBodyLimit:         10000000,  
		ResponseBodyMimeTypes:    []string{"text/html", "text/plain"},
		ResponseBodyLimit:        524288,
		ResponseBodyAccess:       false,
		RuleEngine:               RULE_ENGINE_ON,
		Rules:                    NewRuleGroup(),
		TmpDir:                   "/tmp",
		CollectionTimeout:        3600,
		Logger:                   logger,
		LoggerAtomicLevel:        atom,
	}
	logger.Debug("a new waf instance was created")
	return waf
}