feat: 错误透传规则支持 skip_monitoring 跳过运维监控记录
在每条错误透传规则上新增 skip_monitoring 选项,开启后匹配该规则的错误 不会被记录到 ops_error_logs,减少监控噪音。默认关闭,不影响现有规则。
This commit is contained in:
@@ -44,6 +44,8 @@ type ErrorPassthroughRule struct {
|
||||
PassthroughBody bool `json:"passthrough_body,omitempty"`
|
||||
// CustomMessage holds the value of the "custom_message" field.
|
||||
CustomMessage *string `json:"custom_message,omitempty"`
|
||||
// SkipMonitoring holds the value of the "skip_monitoring" field.
|
||||
SkipMonitoring bool `json:"skip_monitoring,omitempty"`
|
||||
// Description holds the value of the "description" field.
|
||||
Description *string `json:"description,omitempty"`
|
||||
selectValues sql.SelectValues
|
||||
@@ -56,7 +58,7 @@ func (*ErrorPassthroughRule) scanValues(columns []string) ([]any, error) {
|
||||
switch columns[i] {
|
||||
case errorpassthroughrule.FieldErrorCodes, errorpassthroughrule.FieldKeywords, errorpassthroughrule.FieldPlatforms:
|
||||
values[i] = new([]byte)
|
||||
case errorpassthroughrule.FieldEnabled, errorpassthroughrule.FieldPassthroughCode, errorpassthroughrule.FieldPassthroughBody:
|
||||
case errorpassthroughrule.FieldEnabled, errorpassthroughrule.FieldPassthroughCode, errorpassthroughrule.FieldPassthroughBody, errorpassthroughrule.FieldSkipMonitoring:
|
||||
values[i] = new(sql.NullBool)
|
||||
case errorpassthroughrule.FieldID, errorpassthroughrule.FieldPriority, errorpassthroughrule.FieldResponseCode:
|
||||
values[i] = new(sql.NullInt64)
|
||||
@@ -171,6 +173,12 @@ func (_m *ErrorPassthroughRule) assignValues(columns []string, values []any) err
|
||||
_m.CustomMessage = new(string)
|
||||
*_m.CustomMessage = value.String
|
||||
}
|
||||
case errorpassthroughrule.FieldSkipMonitoring:
|
||||
if value, ok := values[i].(*sql.NullBool); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field skip_monitoring", values[i])
|
||||
} else if value.Valid {
|
||||
_m.SkipMonitoring = value.Bool
|
||||
}
|
||||
case errorpassthroughrule.FieldDescription:
|
||||
if value, ok := values[i].(*sql.NullString); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field description", values[i])
|
||||
@@ -257,6 +265,9 @@ func (_m *ErrorPassthroughRule) String() string {
|
||||
builder.WriteString(*v)
|
||||
}
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("skip_monitoring=")
|
||||
builder.WriteString(fmt.Sprintf("%v", _m.SkipMonitoring))
|
||||
builder.WriteString(", ")
|
||||
if v := _m.Description; v != nil {
|
||||
builder.WriteString("description=")
|
||||
builder.WriteString(*v)
|
||||
|
||||
@@ -39,6 +39,8 @@ const (
|
||||
FieldPassthroughBody = "passthrough_body"
|
||||
// FieldCustomMessage holds the string denoting the custom_message field in the database.
|
||||
FieldCustomMessage = "custom_message"
|
||||
// FieldSkipMonitoring holds the string denoting the skip_monitoring field in the database.
|
||||
FieldSkipMonitoring = "skip_monitoring"
|
||||
// FieldDescription holds the string denoting the description field in the database.
|
||||
FieldDescription = "description"
|
||||
// Table holds the table name of the errorpassthroughrule in the database.
|
||||
@@ -61,6 +63,7 @@ var Columns = []string{
|
||||
FieldResponseCode,
|
||||
FieldPassthroughBody,
|
||||
FieldCustomMessage,
|
||||
FieldSkipMonitoring,
|
||||
FieldDescription,
|
||||
}
|
||||
|
||||
@@ -95,6 +98,8 @@ var (
|
||||
DefaultPassthroughCode bool
|
||||
// DefaultPassthroughBody holds the default value on creation for the "passthrough_body" field.
|
||||
DefaultPassthroughBody bool
|
||||
// DefaultSkipMonitoring holds the default value on creation for the "skip_monitoring" field.
|
||||
DefaultSkipMonitoring bool
|
||||
)
|
||||
|
||||
// OrderOption defines the ordering options for the ErrorPassthroughRule queries.
|
||||
@@ -155,6 +160,11 @@ func ByCustomMessage(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldCustomMessage, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// BySkipMonitoring orders the results by the skip_monitoring field.
|
||||
func BySkipMonitoring(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldSkipMonitoring, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByDescription orders the results by the description field.
|
||||
func ByDescription(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldDescription, opts...).ToFunc()
|
||||
|
||||
@@ -104,6 +104,11 @@ func CustomMessage(v string) predicate.ErrorPassthroughRule {
|
||||
return predicate.ErrorPassthroughRule(sql.FieldEQ(FieldCustomMessage, v))
|
||||
}
|
||||
|
||||
// SkipMonitoring applies equality check predicate on the "skip_monitoring" field. It's identical to SkipMonitoringEQ.
|
||||
func SkipMonitoring(v bool) predicate.ErrorPassthroughRule {
|
||||
return predicate.ErrorPassthroughRule(sql.FieldEQ(FieldSkipMonitoring, v))
|
||||
}
|
||||
|
||||
// Description applies equality check predicate on the "description" field. It's identical to DescriptionEQ.
|
||||
func Description(v string) predicate.ErrorPassthroughRule {
|
||||
return predicate.ErrorPassthroughRule(sql.FieldEQ(FieldDescription, v))
|
||||
@@ -544,6 +549,16 @@ func CustomMessageContainsFold(v string) predicate.ErrorPassthroughRule {
|
||||
return predicate.ErrorPassthroughRule(sql.FieldContainsFold(FieldCustomMessage, v))
|
||||
}
|
||||
|
||||
// SkipMonitoringEQ applies the EQ predicate on the "skip_monitoring" field.
|
||||
func SkipMonitoringEQ(v bool) predicate.ErrorPassthroughRule {
|
||||
return predicate.ErrorPassthroughRule(sql.FieldEQ(FieldSkipMonitoring, v))
|
||||
}
|
||||
|
||||
// SkipMonitoringNEQ applies the NEQ predicate on the "skip_monitoring" field.
|
||||
func SkipMonitoringNEQ(v bool) predicate.ErrorPassthroughRule {
|
||||
return predicate.ErrorPassthroughRule(sql.FieldNEQ(FieldSkipMonitoring, v))
|
||||
}
|
||||
|
||||
// DescriptionEQ applies the EQ predicate on the "description" field.
|
||||
func DescriptionEQ(v string) predicate.ErrorPassthroughRule {
|
||||
return predicate.ErrorPassthroughRule(sql.FieldEQ(FieldDescription, v))
|
||||
|
||||
@@ -172,6 +172,20 @@ func (_c *ErrorPassthroughRuleCreate) SetNillableCustomMessage(v *string) *Error
|
||||
return _c
|
||||
}
|
||||
|
||||
// SetSkipMonitoring sets the "skip_monitoring" field.
|
||||
func (_c *ErrorPassthroughRuleCreate) SetSkipMonitoring(v bool) *ErrorPassthroughRuleCreate {
|
||||
_c.mutation.SetSkipMonitoring(v)
|
||||
return _c
|
||||
}
|
||||
|
||||
// SetNillableSkipMonitoring sets the "skip_monitoring" field if the given value is not nil.
|
||||
func (_c *ErrorPassthroughRuleCreate) SetNillableSkipMonitoring(v *bool) *ErrorPassthroughRuleCreate {
|
||||
if v != nil {
|
||||
_c.SetSkipMonitoring(*v)
|
||||
}
|
||||
return _c
|
||||
}
|
||||
|
||||
// SetDescription sets the "description" field.
|
||||
func (_c *ErrorPassthroughRuleCreate) SetDescription(v string) *ErrorPassthroughRuleCreate {
|
||||
_c.mutation.SetDescription(v)
|
||||
@@ -249,6 +263,10 @@ func (_c *ErrorPassthroughRuleCreate) defaults() {
|
||||
v := errorpassthroughrule.DefaultPassthroughBody
|
||||
_c.mutation.SetPassthroughBody(v)
|
||||
}
|
||||
if _, ok := _c.mutation.SkipMonitoring(); !ok {
|
||||
v := errorpassthroughrule.DefaultSkipMonitoring
|
||||
_c.mutation.SetSkipMonitoring(v)
|
||||
}
|
||||
}
|
||||
|
||||
// check runs all checks and user-defined validators on the builder.
|
||||
@@ -287,6 +305,9 @@ func (_c *ErrorPassthroughRuleCreate) check() error {
|
||||
if _, ok := _c.mutation.PassthroughBody(); !ok {
|
||||
return &ValidationError{Name: "passthrough_body", err: errors.New(`ent: missing required field "ErrorPassthroughRule.passthrough_body"`)}
|
||||
}
|
||||
if _, ok := _c.mutation.SkipMonitoring(); !ok {
|
||||
return &ValidationError{Name: "skip_monitoring", err: errors.New(`ent: missing required field "ErrorPassthroughRule.skip_monitoring"`)}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -366,6 +387,10 @@ func (_c *ErrorPassthroughRuleCreate) createSpec() (*ErrorPassthroughRule, *sqlg
|
||||
_spec.SetField(errorpassthroughrule.FieldCustomMessage, field.TypeString, value)
|
||||
_node.CustomMessage = &value
|
||||
}
|
||||
if value, ok := _c.mutation.SkipMonitoring(); ok {
|
||||
_spec.SetField(errorpassthroughrule.FieldSkipMonitoring, field.TypeBool, value)
|
||||
_node.SkipMonitoring = value
|
||||
}
|
||||
if value, ok := _c.mutation.Description(); ok {
|
||||
_spec.SetField(errorpassthroughrule.FieldDescription, field.TypeString, value)
|
||||
_node.Description = &value
|
||||
@@ -608,6 +633,18 @@ func (u *ErrorPassthroughRuleUpsert) ClearCustomMessage() *ErrorPassthroughRuleU
|
||||
return u
|
||||
}
|
||||
|
||||
// SetSkipMonitoring sets the "skip_monitoring" field.
|
||||
func (u *ErrorPassthroughRuleUpsert) SetSkipMonitoring(v bool) *ErrorPassthroughRuleUpsert {
|
||||
u.Set(errorpassthroughrule.FieldSkipMonitoring, v)
|
||||
return u
|
||||
}
|
||||
|
||||
// UpdateSkipMonitoring sets the "skip_monitoring" field to the value that was provided on create.
|
||||
func (u *ErrorPassthroughRuleUpsert) UpdateSkipMonitoring() *ErrorPassthroughRuleUpsert {
|
||||
u.SetExcluded(errorpassthroughrule.FieldSkipMonitoring)
|
||||
return u
|
||||
}
|
||||
|
||||
// SetDescription sets the "description" field.
|
||||
func (u *ErrorPassthroughRuleUpsert) SetDescription(v string) *ErrorPassthroughRuleUpsert {
|
||||
u.Set(errorpassthroughrule.FieldDescription, v)
|
||||
@@ -888,6 +925,20 @@ func (u *ErrorPassthroughRuleUpsertOne) ClearCustomMessage() *ErrorPassthroughRu
|
||||
})
|
||||
}
|
||||
|
||||
// SetSkipMonitoring sets the "skip_monitoring" field.
|
||||
func (u *ErrorPassthroughRuleUpsertOne) SetSkipMonitoring(v bool) *ErrorPassthroughRuleUpsertOne {
|
||||
return u.Update(func(s *ErrorPassthroughRuleUpsert) {
|
||||
s.SetSkipMonitoring(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateSkipMonitoring sets the "skip_monitoring" field to the value that was provided on create.
|
||||
func (u *ErrorPassthroughRuleUpsertOne) UpdateSkipMonitoring() *ErrorPassthroughRuleUpsertOne {
|
||||
return u.Update(func(s *ErrorPassthroughRuleUpsert) {
|
||||
s.UpdateSkipMonitoring()
|
||||
})
|
||||
}
|
||||
|
||||
// SetDescription sets the "description" field.
|
||||
func (u *ErrorPassthroughRuleUpsertOne) SetDescription(v string) *ErrorPassthroughRuleUpsertOne {
|
||||
return u.Update(func(s *ErrorPassthroughRuleUpsert) {
|
||||
@@ -1337,6 +1388,20 @@ func (u *ErrorPassthroughRuleUpsertBulk) ClearCustomMessage() *ErrorPassthroughR
|
||||
})
|
||||
}
|
||||
|
||||
// SetSkipMonitoring sets the "skip_monitoring" field.
|
||||
func (u *ErrorPassthroughRuleUpsertBulk) SetSkipMonitoring(v bool) *ErrorPassthroughRuleUpsertBulk {
|
||||
return u.Update(func(s *ErrorPassthroughRuleUpsert) {
|
||||
s.SetSkipMonitoring(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateSkipMonitoring sets the "skip_monitoring" field to the value that was provided on create.
|
||||
func (u *ErrorPassthroughRuleUpsertBulk) UpdateSkipMonitoring() *ErrorPassthroughRuleUpsertBulk {
|
||||
return u.Update(func(s *ErrorPassthroughRuleUpsert) {
|
||||
s.UpdateSkipMonitoring()
|
||||
})
|
||||
}
|
||||
|
||||
// SetDescription sets the "description" field.
|
||||
func (u *ErrorPassthroughRuleUpsertBulk) SetDescription(v string) *ErrorPassthroughRuleUpsertBulk {
|
||||
return u.Update(func(s *ErrorPassthroughRuleUpsert) {
|
||||
|
||||
@@ -227,6 +227,20 @@ func (_u *ErrorPassthroughRuleUpdate) ClearCustomMessage() *ErrorPassthroughRule
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetSkipMonitoring sets the "skip_monitoring" field.
|
||||
func (_u *ErrorPassthroughRuleUpdate) SetSkipMonitoring(v bool) *ErrorPassthroughRuleUpdate {
|
||||
_u.mutation.SetSkipMonitoring(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNillableSkipMonitoring sets the "skip_monitoring" field if the given value is not nil.
|
||||
func (_u *ErrorPassthroughRuleUpdate) SetNillableSkipMonitoring(v *bool) *ErrorPassthroughRuleUpdate {
|
||||
if v != nil {
|
||||
_u.SetSkipMonitoring(*v)
|
||||
}
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetDescription sets the "description" field.
|
||||
func (_u *ErrorPassthroughRuleUpdate) SetDescription(v string) *ErrorPassthroughRuleUpdate {
|
||||
_u.mutation.SetDescription(v)
|
||||
@@ -387,6 +401,9 @@ func (_u *ErrorPassthroughRuleUpdate) sqlSave(ctx context.Context) (_node int, e
|
||||
if _u.mutation.CustomMessageCleared() {
|
||||
_spec.ClearField(errorpassthroughrule.FieldCustomMessage, field.TypeString)
|
||||
}
|
||||
if value, ok := _u.mutation.SkipMonitoring(); ok {
|
||||
_spec.SetField(errorpassthroughrule.FieldSkipMonitoring, field.TypeBool, value)
|
||||
}
|
||||
if value, ok := _u.mutation.Description(); ok {
|
||||
_spec.SetField(errorpassthroughrule.FieldDescription, field.TypeString, value)
|
||||
}
|
||||
@@ -611,6 +628,20 @@ func (_u *ErrorPassthroughRuleUpdateOne) ClearCustomMessage() *ErrorPassthroughR
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetSkipMonitoring sets the "skip_monitoring" field.
|
||||
func (_u *ErrorPassthroughRuleUpdateOne) SetSkipMonitoring(v bool) *ErrorPassthroughRuleUpdateOne {
|
||||
_u.mutation.SetSkipMonitoring(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNillableSkipMonitoring sets the "skip_monitoring" field if the given value is not nil.
|
||||
func (_u *ErrorPassthroughRuleUpdateOne) SetNillableSkipMonitoring(v *bool) *ErrorPassthroughRuleUpdateOne {
|
||||
if v != nil {
|
||||
_u.SetSkipMonitoring(*v)
|
||||
}
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetDescription sets the "description" field.
|
||||
func (_u *ErrorPassthroughRuleUpdateOne) SetDescription(v string) *ErrorPassthroughRuleUpdateOne {
|
||||
_u.mutation.SetDescription(v)
|
||||
@@ -801,6 +832,9 @@ func (_u *ErrorPassthroughRuleUpdateOne) sqlSave(ctx context.Context) (_node *Er
|
||||
if _u.mutation.CustomMessageCleared() {
|
||||
_spec.ClearField(errorpassthroughrule.FieldCustomMessage, field.TypeString)
|
||||
}
|
||||
if value, ok := _u.mutation.SkipMonitoring(); ok {
|
||||
_spec.SetField(errorpassthroughrule.FieldSkipMonitoring, field.TypeBool, value)
|
||||
}
|
||||
if value, ok := _u.mutation.Description(); ok {
|
||||
_spec.SetField(errorpassthroughrule.FieldDescription, field.TypeString, value)
|
||||
}
|
||||
|
||||
@@ -325,6 +325,7 @@ var (
|
||||
{Name: "response_code", Type: field.TypeInt, Nullable: true},
|
||||
{Name: "passthrough_body", Type: field.TypeBool, Default: true},
|
||||
{Name: "custom_message", Type: field.TypeString, Nullable: true, Size: 2147483647},
|
||||
{Name: "skip_monitoring", Type: field.TypeBool, Default: false},
|
||||
{Name: "description", Type: field.TypeString, Nullable: true, Size: 2147483647},
|
||||
}
|
||||
// ErrorPassthroughRulesTable holds the schema information for the "error_passthrough_rules" table.
|
||||
|
||||
@@ -5776,6 +5776,7 @@ type ErrorPassthroughRuleMutation struct {
|
||||
addresponse_code *int
|
||||
passthrough_body *bool
|
||||
custom_message *string
|
||||
skip_monitoring *bool
|
||||
description *string
|
||||
clearedFields map[string]struct{}
|
||||
done bool
|
||||
@@ -6503,6 +6504,42 @@ func (m *ErrorPassthroughRuleMutation) ResetCustomMessage() {
|
||||
delete(m.clearedFields, errorpassthroughrule.FieldCustomMessage)
|
||||
}
|
||||
|
||||
// SetSkipMonitoring sets the "skip_monitoring" field.
|
||||
func (m *ErrorPassthroughRuleMutation) SetSkipMonitoring(b bool) {
|
||||
m.skip_monitoring = &b
|
||||
}
|
||||
|
||||
// SkipMonitoring returns the value of the "skip_monitoring" field in the mutation.
|
||||
func (m *ErrorPassthroughRuleMutation) SkipMonitoring() (r bool, exists bool) {
|
||||
v := m.skip_monitoring
|
||||
if v == nil {
|
||||
return
|
||||
}
|
||||
return *v, true
|
||||
}
|
||||
|
||||
// OldSkipMonitoring returns the old "skip_monitoring" field's value of the ErrorPassthroughRule entity.
|
||||
// If the ErrorPassthroughRule object wasn't provided to the builder, the object is fetched from the database.
|
||||
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
|
||||
func (m *ErrorPassthroughRuleMutation) OldSkipMonitoring(ctx context.Context) (v bool, err error) {
|
||||
if !m.op.Is(OpUpdateOne) {
|
||||
return v, errors.New("OldSkipMonitoring is only allowed on UpdateOne operations")
|
||||
}
|
||||
if m.id == nil || m.oldValue == nil {
|
||||
return v, errors.New("OldSkipMonitoring requires an ID field in the mutation")
|
||||
}
|
||||
oldValue, err := m.oldValue(ctx)
|
||||
if err != nil {
|
||||
return v, fmt.Errorf("querying old value for OldSkipMonitoring: %w", err)
|
||||
}
|
||||
return oldValue.SkipMonitoring, nil
|
||||
}
|
||||
|
||||
// ResetSkipMonitoring resets all changes to the "skip_monitoring" field.
|
||||
func (m *ErrorPassthroughRuleMutation) ResetSkipMonitoring() {
|
||||
m.skip_monitoring = nil
|
||||
}
|
||||
|
||||
// SetDescription sets the "description" field.
|
||||
func (m *ErrorPassthroughRuleMutation) SetDescription(s string) {
|
||||
m.description = &s
|
||||
@@ -6586,7 +6623,7 @@ func (m *ErrorPassthroughRuleMutation) Type() string {
|
||||
// order to get all numeric fields that were incremented/decremented, call
|
||||
// AddedFields().
|
||||
func (m *ErrorPassthroughRuleMutation) Fields() []string {
|
||||
fields := make([]string, 0, 14)
|
||||
fields := make([]string, 0, 15)
|
||||
if m.created_at != nil {
|
||||
fields = append(fields, errorpassthroughrule.FieldCreatedAt)
|
||||
}
|
||||
@@ -6626,6 +6663,9 @@ func (m *ErrorPassthroughRuleMutation) Fields() []string {
|
||||
if m.custom_message != nil {
|
||||
fields = append(fields, errorpassthroughrule.FieldCustomMessage)
|
||||
}
|
||||
if m.skip_monitoring != nil {
|
||||
fields = append(fields, errorpassthroughrule.FieldSkipMonitoring)
|
||||
}
|
||||
if m.description != nil {
|
||||
fields = append(fields, errorpassthroughrule.FieldDescription)
|
||||
}
|
||||
@@ -6663,6 +6703,8 @@ func (m *ErrorPassthroughRuleMutation) Field(name string) (ent.Value, bool) {
|
||||
return m.PassthroughBody()
|
||||
case errorpassthroughrule.FieldCustomMessage:
|
||||
return m.CustomMessage()
|
||||
case errorpassthroughrule.FieldSkipMonitoring:
|
||||
return m.SkipMonitoring()
|
||||
case errorpassthroughrule.FieldDescription:
|
||||
return m.Description()
|
||||
}
|
||||
@@ -6700,6 +6742,8 @@ func (m *ErrorPassthroughRuleMutation) OldField(ctx context.Context, name string
|
||||
return m.OldPassthroughBody(ctx)
|
||||
case errorpassthroughrule.FieldCustomMessage:
|
||||
return m.OldCustomMessage(ctx)
|
||||
case errorpassthroughrule.FieldSkipMonitoring:
|
||||
return m.OldSkipMonitoring(ctx)
|
||||
case errorpassthroughrule.FieldDescription:
|
||||
return m.OldDescription(ctx)
|
||||
}
|
||||
@@ -6802,6 +6846,13 @@ func (m *ErrorPassthroughRuleMutation) SetField(name string, value ent.Value) er
|
||||
}
|
||||
m.SetCustomMessage(v)
|
||||
return nil
|
||||
case errorpassthroughrule.FieldSkipMonitoring:
|
||||
v, ok := value.(bool)
|
||||
if !ok {
|
||||
return fmt.Errorf("unexpected type %T for field %s", value, name)
|
||||
}
|
||||
m.SetSkipMonitoring(v)
|
||||
return nil
|
||||
case errorpassthroughrule.FieldDescription:
|
||||
v, ok := value.(string)
|
||||
if !ok {
|
||||
@@ -6963,6 +7014,9 @@ func (m *ErrorPassthroughRuleMutation) ResetField(name string) error {
|
||||
case errorpassthroughrule.FieldCustomMessage:
|
||||
m.ResetCustomMessage()
|
||||
return nil
|
||||
case errorpassthroughrule.FieldSkipMonitoring:
|
||||
m.ResetSkipMonitoring()
|
||||
return nil
|
||||
case errorpassthroughrule.FieldDescription:
|
||||
m.ResetDescription()
|
||||
return nil
|
||||
|
||||
@@ -326,6 +326,10 @@ func init() {
|
||||
errorpassthroughruleDescPassthroughBody := errorpassthroughruleFields[9].Descriptor()
|
||||
// errorpassthroughrule.DefaultPassthroughBody holds the default value on creation for the passthrough_body field.
|
||||
errorpassthroughrule.DefaultPassthroughBody = errorpassthroughruleDescPassthroughBody.Default.(bool)
|
||||
// errorpassthroughruleDescSkipMonitoring is the schema descriptor for skip_monitoring field.
|
||||
errorpassthroughruleDescSkipMonitoring := errorpassthroughruleFields[11].Descriptor()
|
||||
// errorpassthroughrule.DefaultSkipMonitoring holds the default value on creation for the skip_monitoring field.
|
||||
errorpassthroughrule.DefaultSkipMonitoring = errorpassthroughruleDescSkipMonitoring.Default.(bool)
|
||||
groupMixin := schema.Group{}.Mixin()
|
||||
groupMixinHooks1 := groupMixin[1].Hooks()
|
||||
group.Hooks[0] = groupMixinHooks1[0]
|
||||
|
||||
@@ -105,6 +105,12 @@ func (ErrorPassthroughRule) Fields() []ent.Field {
|
||||
Optional().
|
||||
Nillable(),
|
||||
|
||||
// skip_monitoring: 是否跳过运维监控记录
|
||||
// true: 匹配此规则的错误不会被记录到 ops_error_logs
|
||||
// false: 正常记录到运维监控(默认行为)
|
||||
field.Bool("skip_monitoring").
|
||||
Default(false),
|
||||
|
||||
// description: 规则描述,用于说明规则的用途
|
||||
field.Text("description").
|
||||
Optional().
|
||||
|
||||
@@ -32,6 +32,7 @@ type CreateErrorPassthroughRuleRequest struct {
|
||||
ResponseCode *int `json:"response_code"`
|
||||
PassthroughBody *bool `json:"passthrough_body"`
|
||||
CustomMessage *string `json:"custom_message"`
|
||||
SkipMonitoring *bool `json:"skip_monitoring"`
|
||||
Description *string `json:"description"`
|
||||
}
|
||||
|
||||
@@ -48,6 +49,7 @@ type UpdateErrorPassthroughRuleRequest struct {
|
||||
ResponseCode *int `json:"response_code"`
|
||||
PassthroughBody *bool `json:"passthrough_body"`
|
||||
CustomMessage *string `json:"custom_message"`
|
||||
SkipMonitoring *bool `json:"skip_monitoring"`
|
||||
Description *string `json:"description"`
|
||||
}
|
||||
|
||||
@@ -122,6 +124,9 @@ func (h *ErrorPassthroughHandler) Create(c *gin.Context) {
|
||||
} else {
|
||||
rule.PassthroughBody = true
|
||||
}
|
||||
if req.SkipMonitoring != nil {
|
||||
rule.SkipMonitoring = *req.SkipMonitoring
|
||||
}
|
||||
rule.ResponseCode = req.ResponseCode
|
||||
rule.CustomMessage = req.CustomMessage
|
||||
rule.Description = req.Description
|
||||
@@ -190,6 +195,7 @@ func (h *ErrorPassthroughHandler) Update(c *gin.Context) {
|
||||
ResponseCode: existing.ResponseCode,
|
||||
PassthroughBody: existing.PassthroughBody,
|
||||
CustomMessage: existing.CustomMessage,
|
||||
SkipMonitoring: existing.SkipMonitoring,
|
||||
Description: existing.Description,
|
||||
}
|
||||
|
||||
@@ -230,6 +236,9 @@ func (h *ErrorPassthroughHandler) Update(c *gin.Context) {
|
||||
if req.Description != nil {
|
||||
rule.Description = req.Description
|
||||
}
|
||||
if req.SkipMonitoring != nil {
|
||||
rule.SkipMonitoring = *req.SkipMonitoring
|
||||
}
|
||||
|
||||
// 确保切片不为 nil
|
||||
if rule.ErrorCodes == nil {
|
||||
|
||||
@@ -544,6 +544,13 @@ func OpsErrorLoggerMiddleware(ops *service.OpsService) gin.HandlerFunc {
|
||||
body := w.buf.Bytes()
|
||||
parsed := parseOpsErrorResponse(body)
|
||||
|
||||
// Skip logging if a passthrough rule with skip_monitoring=true matched.
|
||||
if v, ok := c.Get(service.OpsSkipPassthroughKey); ok {
|
||||
if skip, _ := v.(bool); skip {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Skip logging if the error should be filtered based on settings
|
||||
if shouldSkipOpsErrorLog(c.Request.Context(), ops, parsed.Message, string(body), c.Request.URL.Path) {
|
||||
return
|
||||
|
||||
@@ -18,6 +18,7 @@ type ErrorPassthroughRule struct {
|
||||
ResponseCode *int `json:"response_code"` // 自定义状态码(passthrough_code=false 时使用)
|
||||
PassthroughBody bool `json:"passthrough_body"` // 是否透传原始错误信息
|
||||
CustomMessage *string `json:"custom_message"` // 自定义错误信息(passthrough_body=false 时使用)
|
||||
SkipMonitoring bool `json:"skip_monitoring"` // 是否跳过运维监控记录
|
||||
Description *string `json:"description"` // 规则描述
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
|
||||
@@ -54,7 +54,8 @@ func (r *errorPassthroughRepository) Create(ctx context.Context, rule *model.Err
|
||||
SetPriority(rule.Priority).
|
||||
SetMatchMode(rule.MatchMode).
|
||||
SetPassthroughCode(rule.PassthroughCode).
|
||||
SetPassthroughBody(rule.PassthroughBody)
|
||||
SetPassthroughBody(rule.PassthroughBody).
|
||||
SetSkipMonitoring(rule.SkipMonitoring)
|
||||
|
||||
if len(rule.ErrorCodes) > 0 {
|
||||
builder.SetErrorCodes(rule.ErrorCodes)
|
||||
@@ -90,7 +91,8 @@ func (r *errorPassthroughRepository) Update(ctx context.Context, rule *model.Err
|
||||
SetPriority(rule.Priority).
|
||||
SetMatchMode(rule.MatchMode).
|
||||
SetPassthroughCode(rule.PassthroughCode).
|
||||
SetPassthroughBody(rule.PassthroughBody)
|
||||
SetPassthroughBody(rule.PassthroughBody).
|
||||
SetSkipMonitoring(rule.SkipMonitoring)
|
||||
|
||||
// 处理可选字段
|
||||
if len(rule.ErrorCodes) > 0 {
|
||||
@@ -149,6 +151,7 @@ func (r *errorPassthroughRepository) toModel(e *ent.ErrorPassthroughRule) *model
|
||||
Platforms: e.Platforms,
|
||||
PassthroughCode: e.PassthroughCode,
|
||||
PassthroughBody: e.PassthroughBody,
|
||||
SkipMonitoring: e.SkipMonitoring,
|
||||
CreatedAt: e.CreatedAt,
|
||||
UpdatedAt: e.UpdatedAt,
|
||||
}
|
||||
|
||||
@@ -61,6 +61,11 @@ func applyErrorPassthroughRule(
|
||||
errMsg = *rule.CustomMessage
|
||||
}
|
||||
|
||||
// 命中 skip_monitoring 时在 context 中标记,供 ops_error_logger 跳过记录。
|
||||
if rule.SkipMonitoring {
|
||||
c.Set(OpsSkipPassthroughKey, true)
|
||||
}
|
||||
|
||||
// 与现有 failover 场景保持一致:命中规则时统一返回 upstream_error。
|
||||
errType = "upstream_error"
|
||||
return status, errType, errMsg, true
|
||||
|
||||
@@ -194,6 +194,61 @@ func TestGeminiWriteGeminiMappedError_AppliesRuleFor422(t *testing.T) {
|
||||
assert.Equal(t, "Gemini上游失败", errField["message"])
|
||||
}
|
||||
|
||||
func TestApplyErrorPassthroughRule_SkipMonitoringSetsContextKey(t *testing.T) {
|
||||
gin.SetMode(gin.TestMode)
|
||||
rec := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(rec)
|
||||
|
||||
rule := newNonFailoverPassthroughRule(http.StatusBadRequest, "prompt is too long", http.StatusBadRequest, "上下文超限")
|
||||
rule.SkipMonitoring = true
|
||||
|
||||
ruleSvc := &ErrorPassthroughService{}
|
||||
ruleSvc.setLocalCache([]*model.ErrorPassthroughRule{rule})
|
||||
BindErrorPassthroughService(c, ruleSvc)
|
||||
|
||||
_, _, _, matched := applyErrorPassthroughRule(
|
||||
c,
|
||||
PlatformAnthropic,
|
||||
http.StatusBadRequest,
|
||||
[]byte(`{"error":{"message":"prompt is too long"}}`),
|
||||
http.StatusBadGateway,
|
||||
"upstream_error",
|
||||
"Upstream request failed",
|
||||
)
|
||||
|
||||
assert.True(t, matched)
|
||||
v, exists := c.Get(OpsSkipPassthroughKey)
|
||||
assert.True(t, exists, "OpsSkipPassthroughKey should be set when skip_monitoring=true")
|
||||
assert.True(t, v.(bool))
|
||||
}
|
||||
|
||||
func TestApplyErrorPassthroughRule_NoSkipMonitoringDoesNotSetContextKey(t *testing.T) {
|
||||
gin.SetMode(gin.TestMode)
|
||||
rec := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(rec)
|
||||
|
||||
rule := newNonFailoverPassthroughRule(http.StatusBadRequest, "prompt is too long", http.StatusBadRequest, "上下文超限")
|
||||
rule.SkipMonitoring = false
|
||||
|
||||
ruleSvc := &ErrorPassthroughService{}
|
||||
ruleSvc.setLocalCache([]*model.ErrorPassthroughRule{rule})
|
||||
BindErrorPassthroughService(c, ruleSvc)
|
||||
|
||||
_, _, _, matched := applyErrorPassthroughRule(
|
||||
c,
|
||||
PlatformAnthropic,
|
||||
http.StatusBadRequest,
|
||||
[]byte(`{"error":{"message":"prompt is too long"}}`),
|
||||
http.StatusBadGateway,
|
||||
"upstream_error",
|
||||
"Upstream request failed",
|
||||
)
|
||||
|
||||
assert.True(t, matched)
|
||||
_, exists := c.Get(OpsSkipPassthroughKey)
|
||||
assert.False(t, exists, "OpsSkipPassthroughKey should NOT be set when skip_monitoring=false")
|
||||
}
|
||||
|
||||
func newNonFailoverPassthroughRule(statusCode int, keyword string, respCode int, customMessage string) *model.ErrorPassthroughRule {
|
||||
return &model.ErrorPassthroughRule{
|
||||
ID: 1,
|
||||
|
||||
@@ -20,6 +20,10 @@ const (
|
||||
// retry the specific upstream attempt (not just the client request).
|
||||
// This value is sanitized+trimmed before being persisted.
|
||||
OpsUpstreamRequestBodyKey = "ops_upstream_request_body"
|
||||
|
||||
// OpsSkipPassthroughKey 由 applyErrorPassthroughRule 在命中 skip_monitoring=true 的规则时设置。
|
||||
// ops_error_logger 中间件检查此 key,为 true 时跳过错误记录。
|
||||
OpsSkipPassthroughKey = "ops_skip_passthrough"
|
||||
)
|
||||
|
||||
func setOpsUpstreamError(c *gin.Context, upstreamStatusCode int, upstreamMessage, upstreamDetail string) {
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
-- Add skip_monitoring field to error_passthrough_rules table
|
||||
-- When true, errors matching this rule will not be recorded in ops_error_logs
|
||||
ALTER TABLE error_passthrough_rules
|
||||
ADD COLUMN IF NOT EXISTS skip_monitoring BOOLEAN NOT NULL DEFAULT false;
|
||||
@@ -21,6 +21,7 @@ export interface ErrorPassthroughRule {
|
||||
response_code: number | null
|
||||
passthrough_body: boolean
|
||||
custom_message: string | null
|
||||
skip_monitoring: boolean
|
||||
description: string | null
|
||||
created_at: string
|
||||
updated_at: string
|
||||
@@ -41,6 +42,7 @@ export interface CreateRuleRequest {
|
||||
response_code?: number | null
|
||||
passthrough_body?: boolean
|
||||
custom_message?: string | null
|
||||
skip_monitoring?: boolean
|
||||
description?: string | null
|
||||
}
|
||||
|
||||
@@ -59,6 +61,7 @@ export interface UpdateRuleRequest {
|
||||
response_code?: number | null
|
||||
passthrough_body?: boolean
|
||||
custom_message?: string | null
|
||||
skip_monitoring?: boolean
|
||||
description?: string | null
|
||||
}
|
||||
|
||||
|
||||
@@ -148,6 +148,16 @@
|
||||
{{ rule.passthrough_body ? t('admin.errorPassthrough.passthrough') : t('admin.errorPassthrough.custom') }}
|
||||
</span>
|
||||
</div>
|
||||
<div v-if="rule.skip_monitoring" class="flex items-center gap-1">
|
||||
<Icon
|
||||
name="checkCircle"
|
||||
size="xs"
|
||||
class="text-yellow-500"
|
||||
/>
|
||||
<span class="text-gray-600 dark:text-gray-400">
|
||||
{{ t('admin.errorPassthrough.skipMonitoring') }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-3 py-2">
|
||||
@@ -366,6 +376,19 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Skip Monitoring -->
|
||||
<div class="flex items-center gap-1.5">
|
||||
<input
|
||||
type="checkbox"
|
||||
v-model="form.skip_monitoring"
|
||||
class="h-3.5 w-3.5 rounded border-gray-300 text-yellow-600 focus:ring-yellow-500"
|
||||
/>
|
||||
<span class="text-xs font-medium text-gray-700 dark:text-gray-300">
|
||||
{{ t('admin.errorPassthrough.form.skipMonitoring') }}
|
||||
</span>
|
||||
</div>
|
||||
<p class="input-hint text-xs -mt-3">{{ t('admin.errorPassthrough.form.skipMonitoringHint') }}</p>
|
||||
|
||||
<!-- Enabled -->
|
||||
<div class="flex items-center gap-1.5">
|
||||
<input
|
||||
@@ -453,6 +476,7 @@ const form = reactive({
|
||||
response_code: null as number | null,
|
||||
passthrough_body: true,
|
||||
custom_message: null as string | null,
|
||||
skip_monitoring: false,
|
||||
description: null as string | null
|
||||
})
|
||||
|
||||
@@ -497,6 +521,7 @@ const resetForm = () => {
|
||||
form.response_code = null
|
||||
form.passthrough_body = true
|
||||
form.custom_message = null
|
||||
form.skip_monitoring = false
|
||||
form.description = null
|
||||
errorCodesInput.value = ''
|
||||
keywordsInput.value = ''
|
||||
@@ -520,6 +545,7 @@ const handleEdit = (rule: ErrorPassthroughRule) => {
|
||||
form.response_code = rule.response_code
|
||||
form.passthrough_body = rule.passthrough_body
|
||||
form.custom_message = rule.custom_message
|
||||
form.skip_monitoring = rule.skip_monitoring
|
||||
form.description = rule.description
|
||||
errorCodesInput.value = rule.error_codes.join(', ')
|
||||
keywordsInput.value = rule.keywords.join('\n')
|
||||
@@ -575,6 +601,7 @@ const handleSubmit = async () => {
|
||||
response_code: form.passthrough_code ? null : form.response_code,
|
||||
passthrough_body: form.passthrough_body,
|
||||
custom_message: form.passthrough_body ? null : form.custom_message,
|
||||
skip_monitoring: form.skip_monitoring,
|
||||
description: form.description?.trim() || null
|
||||
}
|
||||
|
||||
|
||||
@@ -3353,6 +3353,7 @@ export default {
|
||||
custom: 'Custom',
|
||||
code: 'Code',
|
||||
body: 'Body',
|
||||
skipMonitoring: 'Skip Monitoring',
|
||||
|
||||
// Columns
|
||||
columns: {
|
||||
@@ -3397,6 +3398,8 @@ export default {
|
||||
passthroughBody: 'Passthrough upstream error message',
|
||||
customMessage: 'Custom error message',
|
||||
customMessagePlaceholder: 'Error message to return to client...',
|
||||
skipMonitoring: 'Skip monitoring',
|
||||
skipMonitoringHint: 'When enabled, errors matching this rule will not be recorded in ops monitoring',
|
||||
enabled: 'Enable this rule'
|
||||
},
|
||||
|
||||
|
||||
@@ -3527,6 +3527,7 @@ export default {
|
||||
custom: '自定义',
|
||||
code: '状态码',
|
||||
body: '消息体',
|
||||
skipMonitoring: '跳过监控',
|
||||
|
||||
// Columns
|
||||
columns: {
|
||||
@@ -3571,6 +3572,8 @@ export default {
|
||||
passthroughBody: '透传上游错误信息',
|
||||
customMessage: '自定义错误信息',
|
||||
customMessagePlaceholder: '返回给客户端的错误信息...',
|
||||
skipMonitoring: '跳过运维监控记录',
|
||||
skipMonitoringHint: '开启后,匹配此规则的错误不会被记录到运维监控中',
|
||||
enabled: '启用此规则'
|
||||
},
|
||||
|
||||
|
||||
Reference in New Issue
Block a user