Update dependencies/vendor (#1659)

This commit is contained in:
Wim
2021-12-12 00:05:15 +01:00
committed by GitHub
parent 658bdd9faa
commit 3893a035be
214 changed files with 8892 additions and 5650 deletions

28
vendor/github.com/mattermost/logr/v2/buffer.go generated vendored Normal file
View File

@@ -0,0 +1,28 @@
package logr
import (
"bytes"
"sync"
)
// Buffer provides a thread-safe buffer useful for logging to memory in unit tests.
type Buffer struct {
buf bytes.Buffer
mux sync.Mutex
}
func (b *Buffer) Read(p []byte) (n int, err error) {
b.mux.Lock()
defer b.mux.Unlock()
return b.buf.Read(p)
}
func (b *Buffer) Write(p []byte) (n int, err error) {
b.mux.Lock()
defer b.mux.Unlock()
return b.buf.Write(p)
}
func (b *Buffer) String() string {
b.mux.Lock()
defer b.mux.Unlock()
return b.buf.String()
}

View File

@@ -31,8 +31,8 @@ type TargetFactory func(targetType string, options json.RawMessage) (logr.Target
type FormatterFactory func(format string, options json.RawMessage) (logr.Formatter, error)
type Factories struct {
targetFactory TargetFactory // can be nil
formatterFactory FormatterFactory // can be nil
TargetFactory TargetFactory // can be nil
FormatterFactory FormatterFactory // can be nil
}
var removeAll = func(ti logr.TargetInfo) bool { return true }
@@ -56,7 +56,7 @@ func ConfigureTargets(lgr *logr.Logr, config map[string]TargetCfg, factories *Fa
}
for name, tcfg := range config {
target, err := newTarget(tcfg.Type, tcfg.Options, factories.targetFactory)
target, err := newTarget(tcfg.Type, tcfg.Options, factories.TargetFactory)
if err != nil {
return fmt.Errorf("error creating log target %s: %w", name, err)
}
@@ -65,7 +65,7 @@ func ConfigureTargets(lgr *logr.Logr, config map[string]TargetCfg, factories *Fa
continue
}
formatter, err := newFormatter(tcfg.Format, tcfg.FormatOptions, factories.formatterFactory)
formatter, err := newFormatter(tcfg.Format, tcfg.FormatOptions, factories.FormatterFactory)
if err != nil {
return fmt.Errorf("error creating formatter for log target %s: %w", name, err)
}

View File

@@ -15,7 +15,7 @@ var (
Space = []byte{' '}
Newline = []byte{'\n'}
Quote = []byte{'"'}
Colon = []byte{'"'}
Colon = []byte{':'}
)
// LogCloner is implemented by `Any` types that require a clone to be provided

View File

@@ -11,6 +11,7 @@ type StdFilter struct {
// is enabled for this filter.
func (lt StdFilter) GetEnabledLevel(level Level) (Level, bool) {
enabled := level.ID <= lt.Lvl.ID
stackTrace := level.ID <= lt.Stacktrace.ID
var levelEnabled Level
if enabled {
@@ -33,6 +34,11 @@ func (lt StdFilter) GetEnabledLevel(level Level) (Level, bool) {
levelEnabled = level
}
}
if stackTrace {
levelEnabled.Stacktrace = true
}
return levelEnabled, enabled
}

View File

@@ -117,3 +117,81 @@ func (s Sugar) Fatalf(format string, args ...interface{}) {
func (s Sugar) Panicf(format string, args ...interface{}) {
s.Logf(Panic, format, args...)
}
//
// K/V style
//
// With returns a new Sugar logger with the specified key/value pairs added to the
// fields list.
func (s Sugar) With(keyValuePairs ...interface{}) Sugar {
return s.logger.With(s.argsToFields(keyValuePairs)...).Sugar()
}
// Tracew outputs at trace level with the specified key/value pairs converted to fields.
func (s Sugar) Tracew(msg string, keyValuePairs ...interface{}) {
s.logger.Log(Trace, msg, s.argsToFields(keyValuePairs)...)
}
// Debugw outputs at debug level with the specified key/value pairs converted to fields.
func (s Sugar) Debugw(msg string, keyValuePairs ...interface{}) {
s.logger.Log(Debug, msg, s.argsToFields(keyValuePairs)...)
}
// Infow outputs at info level with the specified key/value pairs converted to fields.
func (s Sugar) Infow(msg string, keyValuePairs ...interface{}) {
s.logger.Log(Info, msg, s.argsToFields(keyValuePairs)...)
}
// Warnw outputs at warn level with the specified key/value pairs converted to fields.
func (s Sugar) Warnw(msg string, keyValuePairs ...interface{}) {
s.logger.Log(Warn, msg, s.argsToFields(keyValuePairs)...)
}
// Errorw outputs at error level with the specified key/value pairs converted to fields.
func (s Sugar) Errorw(msg string, keyValuePairs ...interface{}) {
s.logger.Log(Error, msg, s.argsToFields(keyValuePairs)...)
}
// Fatalw outputs at fatal level with the specified key/value pairs converted to fields.
func (s Sugar) Fatalw(msg string, keyValuePairs ...interface{}) {
s.logger.Log(Fatal, msg, s.argsToFields(keyValuePairs)...)
}
// Panicw outputs at panic level with the specified key/value pairs converted to fields.
func (s Sugar) Panicw(msg string, keyValuePairs ...interface{}) {
s.logger.Log(Panic, msg, s.argsToFields(keyValuePairs)...)
}
// argsToFields converts an array of args, possibly containing name/value pairs
// into a []Field.
func (s Sugar) argsToFields(keyValuePairs []interface{}) []Field {
if len(keyValuePairs) == 0 {
return nil
}
fields := make([]Field, 0, len(keyValuePairs))
count := len(keyValuePairs)
for i := 0; i < count; {
if fld, ok := keyValuePairs[i].(Field); ok {
fields = append(fields, fld)
i++
continue
}
if i == count-1 {
s.logger.Error("invalid key/value pair", Any("arg", keyValuePairs[i]))
break
}
// we should have a key/value pair now. The key must be a string.
if key, ok := keyValuePairs[i].(string); !ok {
s.logger.Error("invalid key for key/value pair", Int("pos", i))
} else {
fields = append(fields, Any(key, keyValuePairs[i+1]))
}
i += 2
}
return fields
}

View File

@@ -0,0 +1,72 @@
package targets
import (
"strings"
"sync"
"testing"
"github.com/mattermost/logr/v2"
"github.com/mattermost/logr/v2/formatters"
)
// Testing is a simple log target that writes to a (*testing.T) log.
type Testing struct {
mux sync.Mutex
t *testing.T
}
func NewTestingTarget(t *testing.T) *Testing {
return &Testing{
t: t,
}
}
// Init is called once to initialize the target.
func (tt *Testing) Init() error {
return nil
}
// Write outputs bytes to this file target.
func (tt *Testing) Write(p []byte, rec *logr.LogRec) (int, error) {
tt.mux.Lock()
defer tt.mux.Unlock()
if tt.t != nil {
s := strings.TrimSpace(string(p))
tt.t.Log(s)
}
return len(p), nil
}
// Shutdown is called once to free/close any resources.
// Target queue is already drained when this is called.
func (tt *Testing) Shutdown() error {
tt.mux.Lock()
defer tt.mux.Unlock()
tt.t = nil
return nil
}
// CreateTestLogger creates a logger for unit tests. Log records are output to `(*testing.T).Log`.
// A new logger is returned along with a method to shutdown the new logger.
func CreateTestLogger(t *testing.T, levels ...logr.Level) (logger logr.Logger, shutdown func() error) {
lgr, _ := logr.New()
filter := logr.NewCustomFilter(levels...)
formatter := &formatters.Plain{EnableCaller: true}
target := NewTestingTarget(t)
if err := lgr.AddTarget(target, "test", filter, formatter, 1000); err != nil {
t.Fail()
}
shutdown = func() error {
err := lgr.Shutdown()
if err != nil {
target.mux.Lock()
target.t.Error("error shutting down test logger", err)
target.mux.Unlock()
}
return err
}
return lgr.NewLogger(), shutdown
}

View File

@@ -4,6 +4,8 @@
package model
import (
"strings"
"github.com/francoispqt/gojay"
)
@@ -268,7 +270,10 @@ func newAuditCommandArgs(ca *CommandArgs) auditCommandArgs {
cmdargs.ChannelID = ca.ChannelId
cmdargs.TeamID = ca.TeamId
cmdargs.TriggerID = ca.TriggerId
cmdargs.Command = ca.Command
cmdFields := strings.Fields(ca.Command)
if len(cmdFields) > 0 {
cmdargs.Command = cmdFields[0]
}
}
return cmdargs
}

View File

@@ -63,12 +63,8 @@ func (b *Bot) Clone() *Bot {
return &copy
}
// IsValid validates the bot and returns an error if it isn't configured correctly.
func (b *Bot) IsValid() *AppError {
if !IsValidId(b.UserId) {
return NewAppError("Bot.IsValid", "model.bot.is_valid.user_id.app_error", b.Trace(), "", http.StatusBadRequest)
}
// IsValidCreate validates bot for Create call. This skips validations of fields that are auto-filled on Create
func (b *Bot) IsValidCreate() *AppError {
if !IsValidUsername(b.Username) {
return NewAppError("Bot.IsValid", "model.bot.is_valid.username.app_error", b.Trace(), "", http.StatusBadRequest)
}
@@ -85,6 +81,15 @@ func (b *Bot) IsValid() *AppError {
return NewAppError("Bot.IsValid", "model.bot.is_valid.creator_id.app_error", b.Trace(), "", http.StatusBadRequest)
}
return nil
}
// IsValid validates the bot and returns an error if it isn't configured correctly.
func (b *Bot) IsValid() *AppError {
if !IsValidId(b.UserId) {
return NewAppError("Bot.IsValid", "model.bot.is_valid.user_id.app_error", b.Trace(), "", http.StatusBadRequest)
}
if b.CreateAt == 0 {
return NewAppError("Bot.IsValid", "model.bot.is_valid.create_at.app_error", b.Trace(), "", http.StatusBadRequest)
}
@@ -92,8 +97,7 @@ func (b *Bot) IsValid() *AppError {
if b.UpdateAt == 0 {
return NewAppError("Bot.IsValid", "model.bot.is_valid.update_at.app_error", b.Trace(), "", http.StatusBadRequest)
}
return nil
return b.IsValidCreate()
}
// PreSave should be run before saving a new bot to the database.

View File

@@ -56,6 +56,7 @@ type Channel struct {
Shared *bool `json:"shared"`
TotalMsgCountRoot int64 `json:"total_msg_count_root"`
PolicyID *string `json:"policy_id" db:"-"`
LastRootPostAt int64 `json:"last_root_post_at"`
}
type ChannelWithTeamData struct {

View File

@@ -69,7 +69,6 @@ type ChannelMemberForExport struct {
}
func (o *ChannelMember) IsValid() *AppError {
if !IsValidId(o.ChannelId) {
return NewAppError("ChannelMember.IsValid", "model.channel_member.is_valid.channel_id.app_error", nil, "", http.StatusBadRequest)
}
@@ -106,6 +105,11 @@ func (o *ChannelMember) IsValid() *AppError {
}
}
if len(o.Roles) > UserRolesMaxLength {
return NewAppError("ChannelMember.IsValid", "model.channel_member.is_valid.roles_limit.app_error",
map[string]interface{}{"Limit": UserRolesMaxLength}, "", http.StatusBadRequest)
}
return nil
}

View File

@@ -3899,7 +3899,13 @@ func (c *Client4) SearchPostsWithParams(teamId string, params *SearchParameter)
if jsonErr != nil {
return nil, nil, NewAppError("SearchFilesWithParams", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError)
}
r, err := c.DoAPIPost(c.teamRoute(teamId)+"/posts/search", string(js))
var route string
if teamId == "" {
route = c.postsRoute() + "/search"
} else {
route = c.teamRoute(teamId) + "/posts/search"
}
r, err := c.DoAPIPost(route, string(js))
if err != nil {
return nil, BuildResponse(r), err
}
@@ -3917,7 +3923,13 @@ func (c *Client4) SearchPostsWithParams(teamId string, params *SearchParameter)
// SearchPostsWithMatches returns any posts with matching terms string, including.
func (c *Client4) SearchPostsWithMatches(teamId string, terms string, isOrSearch bool) (*PostSearchResults, *Response, error) {
requestBody := map[string]interface{}{"terms": terms, "is_or_search": isOrSearch}
r, err := c.DoAPIPost(c.teamRoute(teamId)+"/posts/search", StringInterfaceToJSON(requestBody))
var route string
if teamId == "" {
route = c.postsRoute() + "/search"
} else {
route = c.teamRoute(teamId) + "/posts/search"
}
r, err := c.DoAPIPost(route, StringInterfaceToJSON(requestBody))
if err != nil {
return nil, BuildResponse(r), err
}

View File

@@ -20,8 +20,9 @@ var MockCWS string
type BillingScheme string
const (
BillingSchemePerSeat = BillingScheme("per_seat")
BillingSchemeFlatFee = BillingScheme("flat_fee")
BillingSchemePerSeat = BillingScheme("per_seat")
BillingSchemeFlatFee = BillingScheme("flat_fee")
BillingSchemeSalesServe = BillingScheme("sales_serve")
)
type RecurringInterval string
@@ -104,7 +105,7 @@ type Address struct {
// PaymentMethod represents methods of payment for a customer.
type PaymentMethod struct {
Type string `json:"type"`
LastFour int `json:"last_four"`
LastFour string `json:"last_four"`
ExpMonth int `json:"exp_month"`
ExpYear int `json:"exp_year"`
CardBrand string `json:"card_brand"`
@@ -169,7 +170,7 @@ type CWSWebhookPayload struct {
type FailedPayment struct {
CardBrand string `json:"card_brand"`
LastFour int `json:"last_four"`
LastFour string `json:"last_four"`
FailureMessage string `json:"failure_message"`
}

View File

@@ -352,6 +352,7 @@ type ServiceSettings struct {
EnableBotAccountCreation *bool `access:"integrations_bot_accounts"`
EnableSVGs *bool `access:"site_posts"`
EnableLatex *bool `access:"site_posts"`
EnableInlineLatex *bool `access:"site_posts"`
EnableAPIChannelDeletion *bool
EnableLocalMode *bool
LocalModeSocketLocation *string // telemetry: none
@@ -736,6 +737,10 @@ func (s *ServiceSettings) SetDefaults(isUpdate bool) {
}
}
if s.EnableInlineLatex == nil {
s.EnableInlineLatex = NewBool(true)
}
if s.EnableLocalMode == nil {
s.EnableLocalMode = NewBool(false)
}
@@ -2610,8 +2615,9 @@ func (s *DataRetentionSettings) SetDefaults() {
}
type JobSettings struct {
RunJobs *bool `access:"write_restrictable,cloud_restrictable"`
RunScheduler *bool `access:"write_restrictable,cloud_restrictable"`
RunJobs *bool `access:"write_restrictable,cloud_restrictable"`
RunScheduler *bool `access:"write_restrictable,cloud_restrictable"`
CleanupJobsThresholdDays *int `access:"write_restrictable,cloud_restrictable"`
}
func (s *JobSettings) SetDefaults() {
@@ -2622,6 +2628,10 @@ func (s *JobSettings) SetDefaults() {
if s.RunScheduler == nil {
s.RunScheduler = NewBool(true)
}
if s.CleanupJobsThresholdDays == nil {
s.CleanupJobsThresholdDays = NewInt(-1)
}
}
type CloudSettings struct {
@@ -3736,9 +3746,11 @@ func (o *Config) Sanitize() {
*o.LdapSettings.BindPassword = FakeSetting
}
*o.FileSettings.PublicLinkSalt = FakeSetting
if o.FileSettings.PublicLinkSalt != nil {
*o.FileSettings.PublicLinkSalt = FakeSetting
}
if *o.FileSettings.AmazonS3SecretAccessKey != "" {
if o.FileSettings.AmazonS3SecretAccessKey != nil && *o.FileSettings.AmazonS3SecretAccessKey != "" {
*o.FileSettings.AmazonS3SecretAccessKey = FakeSetting
}
@@ -3746,7 +3758,7 @@ func (o *Config) Sanitize() {
*o.EmailSettings.SMTPPassword = FakeSetting
}
if *o.GitLabSettings.Secret != "" {
if o.GitLabSettings.Secret != nil && *o.GitLabSettings.Secret != "" {
*o.GitLabSettings.Secret = FakeSetting
}
@@ -3762,10 +3774,17 @@ func (o *Config) Sanitize() {
*o.OpenIdSettings.Secret = FakeSetting
}
*o.SqlSettings.DataSource = FakeSetting
*o.SqlSettings.AtRestEncryptKey = FakeSetting
if o.SqlSettings.DataSource != nil {
*o.SqlSettings.DataSource = FakeSetting
}
*o.ElasticsearchSettings.Password = FakeSetting
if o.SqlSettings.AtRestEncryptKey != nil {
*o.SqlSettings.AtRestEncryptKey = FakeSetting
}
if o.ElasticsearchSettings.Password != nil {
*o.ElasticsearchSettings.Password = FakeSetting
}
for i := range o.SqlSettings.DataSourceReplicas {
o.SqlSettings.DataSourceReplicas[i] = FakeSetting
@@ -3775,7 +3794,9 @@ func (o *Config) Sanitize() {
o.SqlSettings.DataSourceSearchReplicas[i] = FakeSetting
}
if o.MessageExportSettings.GlobalRelaySettings.SMTPPassword != nil && *o.MessageExportSettings.GlobalRelaySettings.SMTPPassword != "" {
if o.MessageExportSettings.GlobalRelaySettings != nil &&
o.MessageExportSettings.GlobalRelaySettings.SMTPPassword != nil &&
*o.MessageExportSettings.GlobalRelaySettings.SMTPPassword != "" {
*o.MessageExportSettings.GlobalRelaySettings.SMTPPassword = FakeSetting
}
@@ -3783,7 +3804,9 @@ func (o *Config) Sanitize() {
*o.ServiceSettings.GfycatAPISecret = FakeSetting
}
*o.ServiceSettings.SplitKey = FakeSetting
if o.ServiceSettings.SplitKey != nil {
*o.ServiceSettings.SplitKey = FakeSetting
}
}
// structToMapFilteredByTag converts a struct into a map removing those fields that has the tag passed

View File

@@ -33,9 +33,6 @@ type FeatureFlags struct {
PluginApps string `plugin_id:"com.mattermost.apps"`
PluginFocalboard string `plugin_id:"focalboard"`
// Enable timed dnd support for user status
TimedDND bool
PermalinkPreviews bool
// Enable the Global Header
@@ -43,6 +40,23 @@ type FeatureFlags struct {
// Enable different team menu button treatments, possible values = ("none", "by_team_name", "inverted_sidebar_bg_color")
AddChannelButton string
// Enable different treatments for first time users, possible values = ("none", "tour_point", "around_input")
PrewrittenMessages string
// Enable different treatments for first time users, possible values = ("none", "tips_and_next_steps")
DownloadAppsCTA string
// Determine whether when a user gets created, they'll have noisy notifications e.g. Send desktop notifications for all activity
NewAccountNoisy bool
// Enable Boards Unfurl Preview
BoardsUnfurl bool
// Enable Calls plugin support in the mobile app
CallsMobile bool
// Start A/B tour tips automatically, possible values = ("none", "auto")
AutoTour string
}
func (f *FeatureFlags) SetDefaults() {
@@ -54,10 +68,15 @@ func (f *FeatureFlags) SetDefaults() {
f.AppsEnabled = false
f.PluginApps = ""
f.PluginFocalboard = ""
f.TimedDND = false
f.PermalinkPreviews = true
f.GlobalHeader = true
f.AddChannelButton = "by_team_name"
f.PrewrittenMessages = "tour_point"
f.DownloadAppsCTA = "tips_and_next_steps"
f.NewAccountNoisy = false
f.BoardsUnfurl = true
f.CallsMobile = false
f.AutoTour = "none"
}
func (f *FeatureFlags) Plugins() map[string]string {

View File

@@ -115,6 +115,14 @@ func (p *PostAction) Equals(input *PostAction) bool {
}
// Compare PostActionIntegration
// If input is nil, then return true if original is also nil.
// Else return false.
if input.Integration == nil {
return p.Integration == nil
}
// Both are unequal and not nil.
if p.Integration.URL != input.Integration.URL {
return false
}

View File

@@ -9,6 +9,7 @@ const (
PostEmbedOpengraph PostEmbedType = "opengraph"
PostEmbedLink PostEmbedType = "link"
PostEmbedPermalink PostEmbedType = "permalink"
PostEmbedBoards PostEmbedType = "boards"
)
type PostEmbedType string

View File

@@ -4,6 +4,7 @@
package model
import (
"net/http"
"strconv"
"strings"
@@ -78,6 +79,27 @@ func (s *Session) DeepCopy() *Session {
return &copySession
}
func (s *Session) IsValid() *AppError {
if !IsValidId(s.Id) {
return NewAppError("Session.IsValid", "model.session.is_valid.id.app_error", nil, "", http.StatusBadRequest)
}
if !IsValidId(s.UserId) {
return NewAppError("Session.IsValid", "model.session.is_valid.user_id.app_error", nil, "", http.StatusBadRequest)
}
if s.CreateAt == 0 {
return NewAppError("Session.IsValid", "model.session.is_valid.create_at.app_error", nil, "", http.StatusBadRequest)
}
if len(s.Roles) > UserRolesMaxLength {
return NewAppError("Session.IsValid", "model.session.is_valid.roles_limit.app_error",
map[string]interface{}{"Limit": UserRolesMaxLength}, "session_id="+s.Id, http.StatusBadRequest)
}
return nil
}
func (s *Session) PreSave() {
if s.Id == "" {
s.Id = NewId()

View File

@@ -238,6 +238,7 @@ func (scf *SharedChannelAttachment) IsValid() *AppError {
type SharedChannelFilterOpts struct {
TeamId string
CreatorId string
MemberId string
ExcludeHome bool
ExcludeRemote bool
}

View File

@@ -98,7 +98,6 @@ func TeamMemberWithErrorToString(o *TeamMemberWithError) string {
}
func (o *TeamMember) IsValid() *AppError {
if !IsValidId(o.TeamId) {
return NewAppError("TeamMember.IsValid", "model.team_member.is_valid.team_id.app_error", nil, "", http.StatusBadRequest)
}
@@ -107,6 +106,11 @@ func (o *TeamMember) IsValid() *AppError {
return NewAppError("TeamMember.IsValid", "model.team_member.is_valid.user_id.app_error", nil, "", http.StatusBadRequest)
}
if len(o.Roles) > UserRolesMaxLength {
return NewAppError("TeamMember.IsValid", "model.team_member.is_valid.roles_limit.app_error",
map[string]interface{}{"Limit": UserRolesMaxLength}, "", http.StatusBadRequest)
}
return nil
}

View File

@@ -60,6 +60,7 @@ const (
UserPasswordMaxLength = 72
UserLocaleMaxLength = 5
UserTimezoneMaxRunes = 256
UserRolesMaxLength = 256
)
//msgp:tuple User
@@ -261,7 +262,6 @@ func (u *User) DeepCopy() *User {
// IsValid validates the user and returns an error if it isn't configured
// correctly.
func (u *User) IsValid() *AppError {
if !IsValidId(u.Id) {
return InvalidUserError("id", "")
}
@@ -332,6 +332,11 @@ func (u *User) IsValid() *AppError {
}
}
if len(u.Roles) > UserRolesMaxLength {
return NewAppError("User.IsValid", "model.user.is_valid.roles_limit.app_error",
map[string]interface{}{"Limit": UserRolesMaxLength}, "user_id="+u.Id, http.StatusBadRequest)
}
return nil
}

View File

@@ -6,6 +6,7 @@ package model
import (
"bytes"
"crypto/rand"
"database/sql/driver"
"encoding/base32"
"encoding/json"
"fmt"
@@ -24,6 +25,7 @@ import (
"github.com/mattermost/mattermost-server/v6/shared/i18n"
"github.com/pborman/uuid"
"github.com/pkg/errors"
)
const (
@@ -72,6 +74,30 @@ func (sa StringArray) Equals(input StringArray) bool {
return true
}
// Value converts StringArray to database value
func (sa StringArray) Value() (driver.Value, error) {
return json.Marshal(sa)
}
// Scan converts database column value to StringArray
func (sa *StringArray) Scan(value interface{}) error {
if value == nil {
return nil
}
buf, ok := value.([]byte)
if ok {
return json.Unmarshal(buf, sa)
}
str, ok := value.(string)
if ok {
return json.Unmarshal([]byte(str), sa)
}
return errors.New("received value is neither a byte slice nor string")
}
var translateFunc i18n.TranslateFunc
var translateFuncOnce sync.Once

View File

@@ -13,8 +13,7 @@ import (
// It should be maintained in chronological order with most current
// release at the front of the list.
var versions = []string{
"6.0.2",
"6.0.1",
"6.1.0",
"6.0.0",
"5.39.0",
"5.38.0",

View File

@@ -49,6 +49,9 @@ type LogRec = logr.LogRec
type LogCloner = logr.LogCloner
type MetricsCollector = logr.MetricsCollector
type TargetCfg = logrcfg.TargetCfg
type TargetFactory = logrcfg.TargetFactory
type FormatterFactory = logrcfg.FormatterFactory
type Factories = logrcfg.Factories
type Sugar = logr.Sugar
// LoggerConfiguration is a map of LogTarget configurations.
@@ -179,7 +182,10 @@ func NewLogger(options ...Option) (*Logger, error) {
// For each case JSON containing log targets is provided. Target name collisions are resolved
// using the following precedence:
// cfgFile > cfgEscaped
func (l *Logger) Configure(cfgFile string, cfgEscaped string) error {
//
// An optional set of factories can be provided which will be called to create any target
// types or formatters not built-in.
func (l *Logger) Configure(cfgFile string, cfgEscaped string, factories *Factories) error {
if atomic.LoadInt32(l.lockConfig) != 0 {
return ErrConfigurationLock
}
@@ -213,16 +219,18 @@ func (l *Logger) Configure(cfgFile string, cfgEscaped string) error {
return nil
}
return logrcfg.ConfigureTargets(l.log.Logr(), cfgMap.toTargetCfg(), nil)
return logrcfg.ConfigureTargets(l.log.Logr(), cfgMap.toTargetCfg(), factories)
}
// ConfigureTargets provides a new configuration for this logger via a `LoggerConfig` map.
// Typically `mlog.Configure` is used instead which accepts JSON formatted configuration.
func (l *Logger) ConfigureTargets(cfg LoggerConfiguration) error {
// An optional set of factories can be provided which will be called to create any target
// types or formatters not built-in.
func (l *Logger) ConfigureTargets(cfg LoggerConfiguration, factories *Factories) error {
if atomic.LoadInt32(l.lockConfig) != 0 {
return ErrConfigurationLock
}
return logrcfg.ConfigureTargets(l.log.Logr(), cfg.toTargetCfg(), nil)
return logrcfg.ConfigureTargets(l.log.Logr(), cfg.toTargetCfg(), factories)
}
// LockConfiguration disallows further configuration changes until `UnlockConfiguration`
@@ -405,6 +413,22 @@ func GetPackageName(f string) string {
return f
}
// ShouldQuote returns true if val contains any characters that might be unsafe
// when injecting log output into an aggregator, viewer or report.
// Returning true means that val should be surrounded by quotation marks before being
// output into logs.
func ShouldQuote(val string) bool {
for _, c := range val {
if !((c >= '0' && c <= '9') ||
(c >= 'a' && c <= 'z') ||
(c >= 'A' && c <= 'Z') ||
c == '-' || c == '.' || c == '_' || c == '/' || c == '@' || c == '^' || c == '+') {
return true
}
}
return false
}
type logWriter struct {
logger *Logger
}