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"`
|
PassthroughBody bool `json:"passthrough_body,omitempty"`
|
||||||
// CustomMessage holds the value of the "custom_message" field.
|
// CustomMessage holds the value of the "custom_message" field.
|
||||||
CustomMessage *string `json:"custom_message,omitempty"`
|
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 holds the value of the "description" field.
|
||||||
Description *string `json:"description,omitempty"`
|
Description *string `json:"description,omitempty"`
|
||||||
selectValues sql.SelectValues
|
selectValues sql.SelectValues
|
||||||
@@ -56,7 +58,7 @@ func (*ErrorPassthroughRule) scanValues(columns []string) ([]any, error) {
|
|||||||
switch columns[i] {
|
switch columns[i] {
|
||||||
case errorpassthroughrule.FieldErrorCodes, errorpassthroughrule.FieldKeywords, errorpassthroughrule.FieldPlatforms:
|
case errorpassthroughrule.FieldErrorCodes, errorpassthroughrule.FieldKeywords, errorpassthroughrule.FieldPlatforms:
|
||||||
values[i] = new([]byte)
|
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)
|
values[i] = new(sql.NullBool)
|
||||||
case errorpassthroughrule.FieldID, errorpassthroughrule.FieldPriority, errorpassthroughrule.FieldResponseCode:
|
case errorpassthroughrule.FieldID, errorpassthroughrule.FieldPriority, errorpassthroughrule.FieldResponseCode:
|
||||||
values[i] = new(sql.NullInt64)
|
values[i] = new(sql.NullInt64)
|
||||||
@@ -171,6 +173,12 @@ func (_m *ErrorPassthroughRule) assignValues(columns []string, values []any) err
|
|||||||
_m.CustomMessage = new(string)
|
_m.CustomMessage = new(string)
|
||||||
*_m.CustomMessage = value.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:
|
case errorpassthroughrule.FieldDescription:
|
||||||
if value, ok := values[i].(*sql.NullString); !ok {
|
if value, ok := values[i].(*sql.NullString); !ok {
|
||||||
return fmt.Errorf("unexpected type %T for field description", values[i])
|
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(*v)
|
||||||
}
|
}
|
||||||
builder.WriteString(", ")
|
builder.WriteString(", ")
|
||||||
|
builder.WriteString("skip_monitoring=")
|
||||||
|
builder.WriteString(fmt.Sprintf("%v", _m.SkipMonitoring))
|
||||||
|
builder.WriteString(", ")
|
||||||
if v := _m.Description; v != nil {
|
if v := _m.Description; v != nil {
|
||||||
builder.WriteString("description=")
|
builder.WriteString("description=")
|
||||||
builder.WriteString(*v)
|
builder.WriteString(*v)
|
||||||
|
|||||||
@@ -39,6 +39,8 @@ const (
|
|||||||
FieldPassthroughBody = "passthrough_body"
|
FieldPassthroughBody = "passthrough_body"
|
||||||
// FieldCustomMessage holds the string denoting the custom_message field in the database.
|
// FieldCustomMessage holds the string denoting the custom_message field in the database.
|
||||||
FieldCustomMessage = "custom_message"
|
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 holds the string denoting the description field in the database.
|
||||||
FieldDescription = "description"
|
FieldDescription = "description"
|
||||||
// Table holds the table name of the errorpassthroughrule in the database.
|
// Table holds the table name of the errorpassthroughrule in the database.
|
||||||
@@ -61,6 +63,7 @@ var Columns = []string{
|
|||||||
FieldResponseCode,
|
FieldResponseCode,
|
||||||
FieldPassthroughBody,
|
FieldPassthroughBody,
|
||||||
FieldCustomMessage,
|
FieldCustomMessage,
|
||||||
|
FieldSkipMonitoring,
|
||||||
FieldDescription,
|
FieldDescription,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,6 +98,8 @@ var (
|
|||||||
DefaultPassthroughCode bool
|
DefaultPassthroughCode bool
|
||||||
// DefaultPassthroughBody holds the default value on creation for the "passthrough_body" field.
|
// DefaultPassthroughBody holds the default value on creation for the "passthrough_body" field.
|
||||||
DefaultPassthroughBody bool
|
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.
|
// 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()
|
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.
|
// ByDescription orders the results by the description field.
|
||||||
func ByDescription(opts ...sql.OrderTermOption) OrderOption {
|
func ByDescription(opts ...sql.OrderTermOption) OrderOption {
|
||||||
return sql.OrderByField(FieldDescription, opts...).ToFunc()
|
return sql.OrderByField(FieldDescription, opts...).ToFunc()
|
||||||
|
|||||||
@@ -104,6 +104,11 @@ func CustomMessage(v string) predicate.ErrorPassthroughRule {
|
|||||||
return predicate.ErrorPassthroughRule(sql.FieldEQ(FieldCustomMessage, v))
|
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.
|
// Description applies equality check predicate on the "description" field. It's identical to DescriptionEQ.
|
||||||
func Description(v string) predicate.ErrorPassthroughRule {
|
func Description(v string) predicate.ErrorPassthroughRule {
|
||||||
return predicate.ErrorPassthroughRule(sql.FieldEQ(FieldDescription, v))
|
return predicate.ErrorPassthroughRule(sql.FieldEQ(FieldDescription, v))
|
||||||
@@ -544,6 +549,16 @@ func CustomMessageContainsFold(v string) predicate.ErrorPassthroughRule {
|
|||||||
return predicate.ErrorPassthroughRule(sql.FieldContainsFold(FieldCustomMessage, v))
|
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.
|
// DescriptionEQ applies the EQ predicate on the "description" field.
|
||||||
func DescriptionEQ(v string) predicate.ErrorPassthroughRule {
|
func DescriptionEQ(v string) predicate.ErrorPassthroughRule {
|
||||||
return predicate.ErrorPassthroughRule(sql.FieldEQ(FieldDescription, v))
|
return predicate.ErrorPassthroughRule(sql.FieldEQ(FieldDescription, v))
|
||||||
|
|||||||
@@ -172,6 +172,20 @@ func (_c *ErrorPassthroughRuleCreate) SetNillableCustomMessage(v *string) *Error
|
|||||||
return _c
|
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.
|
// SetDescription sets the "description" field.
|
||||||
func (_c *ErrorPassthroughRuleCreate) SetDescription(v string) *ErrorPassthroughRuleCreate {
|
func (_c *ErrorPassthroughRuleCreate) SetDescription(v string) *ErrorPassthroughRuleCreate {
|
||||||
_c.mutation.SetDescription(v)
|
_c.mutation.SetDescription(v)
|
||||||
@@ -249,6 +263,10 @@ func (_c *ErrorPassthroughRuleCreate) defaults() {
|
|||||||
v := errorpassthroughrule.DefaultPassthroughBody
|
v := errorpassthroughrule.DefaultPassthroughBody
|
||||||
_c.mutation.SetPassthroughBody(v)
|
_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.
|
// 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 {
|
if _, ok := _c.mutation.PassthroughBody(); !ok {
|
||||||
return &ValidationError{Name: "passthrough_body", err: errors.New(`ent: missing required field "ErrorPassthroughRule.passthrough_body"`)}
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -366,6 +387,10 @@ func (_c *ErrorPassthroughRuleCreate) createSpec() (*ErrorPassthroughRule, *sqlg
|
|||||||
_spec.SetField(errorpassthroughrule.FieldCustomMessage, field.TypeString, value)
|
_spec.SetField(errorpassthroughrule.FieldCustomMessage, field.TypeString, value)
|
||||||
_node.CustomMessage = &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 {
|
if value, ok := _c.mutation.Description(); ok {
|
||||||
_spec.SetField(errorpassthroughrule.FieldDescription, field.TypeString, value)
|
_spec.SetField(errorpassthroughrule.FieldDescription, field.TypeString, value)
|
||||||
_node.Description = &value
|
_node.Description = &value
|
||||||
@@ -608,6 +633,18 @@ func (u *ErrorPassthroughRuleUpsert) ClearCustomMessage() *ErrorPassthroughRuleU
|
|||||||
return u
|
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.
|
// SetDescription sets the "description" field.
|
||||||
func (u *ErrorPassthroughRuleUpsert) SetDescription(v string) *ErrorPassthroughRuleUpsert {
|
func (u *ErrorPassthroughRuleUpsert) SetDescription(v string) *ErrorPassthroughRuleUpsert {
|
||||||
u.Set(errorpassthroughrule.FieldDescription, v)
|
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.
|
// SetDescription sets the "description" field.
|
||||||
func (u *ErrorPassthroughRuleUpsertOne) SetDescription(v string) *ErrorPassthroughRuleUpsertOne {
|
func (u *ErrorPassthroughRuleUpsertOne) SetDescription(v string) *ErrorPassthroughRuleUpsertOne {
|
||||||
return u.Update(func(s *ErrorPassthroughRuleUpsert) {
|
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.
|
// SetDescription sets the "description" field.
|
||||||
func (u *ErrorPassthroughRuleUpsertBulk) SetDescription(v string) *ErrorPassthroughRuleUpsertBulk {
|
func (u *ErrorPassthroughRuleUpsertBulk) SetDescription(v string) *ErrorPassthroughRuleUpsertBulk {
|
||||||
return u.Update(func(s *ErrorPassthroughRuleUpsert) {
|
return u.Update(func(s *ErrorPassthroughRuleUpsert) {
|
||||||
|
|||||||
@@ -227,6 +227,20 @@ func (_u *ErrorPassthroughRuleUpdate) ClearCustomMessage() *ErrorPassthroughRule
|
|||||||
return _u
|
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.
|
// SetDescription sets the "description" field.
|
||||||
func (_u *ErrorPassthroughRuleUpdate) SetDescription(v string) *ErrorPassthroughRuleUpdate {
|
func (_u *ErrorPassthroughRuleUpdate) SetDescription(v string) *ErrorPassthroughRuleUpdate {
|
||||||
_u.mutation.SetDescription(v)
|
_u.mutation.SetDescription(v)
|
||||||
@@ -387,6 +401,9 @@ func (_u *ErrorPassthroughRuleUpdate) sqlSave(ctx context.Context) (_node int, e
|
|||||||
if _u.mutation.CustomMessageCleared() {
|
if _u.mutation.CustomMessageCleared() {
|
||||||
_spec.ClearField(errorpassthroughrule.FieldCustomMessage, field.TypeString)
|
_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 {
|
if value, ok := _u.mutation.Description(); ok {
|
||||||
_spec.SetField(errorpassthroughrule.FieldDescription, field.TypeString, value)
|
_spec.SetField(errorpassthroughrule.FieldDescription, field.TypeString, value)
|
||||||
}
|
}
|
||||||
@@ -611,6 +628,20 @@ func (_u *ErrorPassthroughRuleUpdateOne) ClearCustomMessage() *ErrorPassthroughR
|
|||||||
return _u
|
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.
|
// SetDescription sets the "description" field.
|
||||||
func (_u *ErrorPassthroughRuleUpdateOne) SetDescription(v string) *ErrorPassthroughRuleUpdateOne {
|
func (_u *ErrorPassthroughRuleUpdateOne) SetDescription(v string) *ErrorPassthroughRuleUpdateOne {
|
||||||
_u.mutation.SetDescription(v)
|
_u.mutation.SetDescription(v)
|
||||||
@@ -801,6 +832,9 @@ func (_u *ErrorPassthroughRuleUpdateOne) sqlSave(ctx context.Context) (_node *Er
|
|||||||
if _u.mutation.CustomMessageCleared() {
|
if _u.mutation.CustomMessageCleared() {
|
||||||
_spec.ClearField(errorpassthroughrule.FieldCustomMessage, field.TypeString)
|
_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 {
|
if value, ok := _u.mutation.Description(); ok {
|
||||||
_spec.SetField(errorpassthroughrule.FieldDescription, field.TypeString, value)
|
_spec.SetField(errorpassthroughrule.FieldDescription, field.TypeString, value)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -325,6 +325,7 @@ var (
|
|||||||
{Name: "response_code", Type: field.TypeInt, Nullable: true},
|
{Name: "response_code", Type: field.TypeInt, Nullable: true},
|
||||||
{Name: "passthrough_body", Type: field.TypeBool, Default: true},
|
{Name: "passthrough_body", Type: field.TypeBool, Default: true},
|
||||||
{Name: "custom_message", Type: field.TypeString, Nullable: true, Size: 2147483647},
|
{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},
|
{Name: "description", Type: field.TypeString, Nullable: true, Size: 2147483647},
|
||||||
}
|
}
|
||||||
// ErrorPassthroughRulesTable holds the schema information for the "error_passthrough_rules" table.
|
// ErrorPassthroughRulesTable holds the schema information for the "error_passthrough_rules" table.
|
||||||
|
|||||||
@@ -5776,6 +5776,7 @@ type ErrorPassthroughRuleMutation struct {
|
|||||||
addresponse_code *int
|
addresponse_code *int
|
||||||
passthrough_body *bool
|
passthrough_body *bool
|
||||||
custom_message *string
|
custom_message *string
|
||||||
|
skip_monitoring *bool
|
||||||
description *string
|
description *string
|
||||||
clearedFields map[string]struct{}
|
clearedFields map[string]struct{}
|
||||||
done bool
|
done bool
|
||||||
@@ -6503,6 +6504,42 @@ func (m *ErrorPassthroughRuleMutation) ResetCustomMessage() {
|
|||||||
delete(m.clearedFields, errorpassthroughrule.FieldCustomMessage)
|
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.
|
// SetDescription sets the "description" field.
|
||||||
func (m *ErrorPassthroughRuleMutation) SetDescription(s string) {
|
func (m *ErrorPassthroughRuleMutation) SetDescription(s string) {
|
||||||
m.description = &s
|
m.description = &s
|
||||||
@@ -6586,7 +6623,7 @@ func (m *ErrorPassthroughRuleMutation) Type() string {
|
|||||||
// order to get all numeric fields that were incremented/decremented, call
|
// order to get all numeric fields that were incremented/decremented, call
|
||||||
// AddedFields().
|
// AddedFields().
|
||||||
func (m *ErrorPassthroughRuleMutation) Fields() []string {
|
func (m *ErrorPassthroughRuleMutation) Fields() []string {
|
||||||
fields := make([]string, 0, 14)
|
fields := make([]string, 0, 15)
|
||||||
if m.created_at != nil {
|
if m.created_at != nil {
|
||||||
fields = append(fields, errorpassthroughrule.FieldCreatedAt)
|
fields = append(fields, errorpassthroughrule.FieldCreatedAt)
|
||||||
}
|
}
|
||||||
@@ -6626,6 +6663,9 @@ func (m *ErrorPassthroughRuleMutation) Fields() []string {
|
|||||||
if m.custom_message != nil {
|
if m.custom_message != nil {
|
||||||
fields = append(fields, errorpassthroughrule.FieldCustomMessage)
|
fields = append(fields, errorpassthroughrule.FieldCustomMessage)
|
||||||
}
|
}
|
||||||
|
if m.skip_monitoring != nil {
|
||||||
|
fields = append(fields, errorpassthroughrule.FieldSkipMonitoring)
|
||||||
|
}
|
||||||
if m.description != nil {
|
if m.description != nil {
|
||||||
fields = append(fields, errorpassthroughrule.FieldDescription)
|
fields = append(fields, errorpassthroughrule.FieldDescription)
|
||||||
}
|
}
|
||||||
@@ -6663,6 +6703,8 @@ func (m *ErrorPassthroughRuleMutation) Field(name string) (ent.Value, bool) {
|
|||||||
return m.PassthroughBody()
|
return m.PassthroughBody()
|
||||||
case errorpassthroughrule.FieldCustomMessage:
|
case errorpassthroughrule.FieldCustomMessage:
|
||||||
return m.CustomMessage()
|
return m.CustomMessage()
|
||||||
|
case errorpassthroughrule.FieldSkipMonitoring:
|
||||||
|
return m.SkipMonitoring()
|
||||||
case errorpassthroughrule.FieldDescription:
|
case errorpassthroughrule.FieldDescription:
|
||||||
return m.Description()
|
return m.Description()
|
||||||
}
|
}
|
||||||
@@ -6700,6 +6742,8 @@ func (m *ErrorPassthroughRuleMutation) OldField(ctx context.Context, name string
|
|||||||
return m.OldPassthroughBody(ctx)
|
return m.OldPassthroughBody(ctx)
|
||||||
case errorpassthroughrule.FieldCustomMessage:
|
case errorpassthroughrule.FieldCustomMessage:
|
||||||
return m.OldCustomMessage(ctx)
|
return m.OldCustomMessage(ctx)
|
||||||
|
case errorpassthroughrule.FieldSkipMonitoring:
|
||||||
|
return m.OldSkipMonitoring(ctx)
|
||||||
case errorpassthroughrule.FieldDescription:
|
case errorpassthroughrule.FieldDescription:
|
||||||
return m.OldDescription(ctx)
|
return m.OldDescription(ctx)
|
||||||
}
|
}
|
||||||
@@ -6802,6 +6846,13 @@ func (m *ErrorPassthroughRuleMutation) SetField(name string, value ent.Value) er
|
|||||||
}
|
}
|
||||||
m.SetCustomMessage(v)
|
m.SetCustomMessage(v)
|
||||||
return nil
|
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:
|
case errorpassthroughrule.FieldDescription:
|
||||||
v, ok := value.(string)
|
v, ok := value.(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
@@ -6963,6 +7014,9 @@ func (m *ErrorPassthroughRuleMutation) ResetField(name string) error {
|
|||||||
case errorpassthroughrule.FieldCustomMessage:
|
case errorpassthroughrule.FieldCustomMessage:
|
||||||
m.ResetCustomMessage()
|
m.ResetCustomMessage()
|
||||||
return nil
|
return nil
|
||||||
|
case errorpassthroughrule.FieldSkipMonitoring:
|
||||||
|
m.ResetSkipMonitoring()
|
||||||
|
return nil
|
||||||
case errorpassthroughrule.FieldDescription:
|
case errorpassthroughrule.FieldDescription:
|
||||||
m.ResetDescription()
|
m.ResetDescription()
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -326,6 +326,10 @@ func init() {
|
|||||||
errorpassthroughruleDescPassthroughBody := errorpassthroughruleFields[9].Descriptor()
|
errorpassthroughruleDescPassthroughBody := errorpassthroughruleFields[9].Descriptor()
|
||||||
// errorpassthroughrule.DefaultPassthroughBody holds the default value on creation for the passthrough_body field.
|
// errorpassthroughrule.DefaultPassthroughBody holds the default value on creation for the passthrough_body field.
|
||||||
errorpassthroughrule.DefaultPassthroughBody = errorpassthroughruleDescPassthroughBody.Default.(bool)
|
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()
|
groupMixin := schema.Group{}.Mixin()
|
||||||
groupMixinHooks1 := groupMixin[1].Hooks()
|
groupMixinHooks1 := groupMixin[1].Hooks()
|
||||||
group.Hooks[0] = groupMixinHooks1[0]
|
group.Hooks[0] = groupMixinHooks1[0]
|
||||||
|
|||||||
@@ -105,6 +105,12 @@ func (ErrorPassthroughRule) Fields() []ent.Field {
|
|||||||
Optional().
|
Optional().
|
||||||
Nillable(),
|
Nillable(),
|
||||||
|
|
||||||
|
// skip_monitoring: 是否跳过运维监控记录
|
||||||
|
// true: 匹配此规则的错误不会被记录到 ops_error_logs
|
||||||
|
// false: 正常记录到运维监控(默认行为)
|
||||||
|
field.Bool("skip_monitoring").
|
||||||
|
Default(false),
|
||||||
|
|
||||||
// description: 规则描述,用于说明规则的用途
|
// description: 规则描述,用于说明规则的用途
|
||||||
field.Text("description").
|
field.Text("description").
|
||||||
Optional().
|
Optional().
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ type CreateErrorPassthroughRuleRequest struct {
|
|||||||
ResponseCode *int `json:"response_code"`
|
ResponseCode *int `json:"response_code"`
|
||||||
PassthroughBody *bool `json:"passthrough_body"`
|
PassthroughBody *bool `json:"passthrough_body"`
|
||||||
CustomMessage *string `json:"custom_message"`
|
CustomMessage *string `json:"custom_message"`
|
||||||
|
SkipMonitoring *bool `json:"skip_monitoring"`
|
||||||
Description *string `json:"description"`
|
Description *string `json:"description"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,6 +49,7 @@ type UpdateErrorPassthroughRuleRequest struct {
|
|||||||
ResponseCode *int `json:"response_code"`
|
ResponseCode *int `json:"response_code"`
|
||||||
PassthroughBody *bool `json:"passthrough_body"`
|
PassthroughBody *bool `json:"passthrough_body"`
|
||||||
CustomMessage *string `json:"custom_message"`
|
CustomMessage *string `json:"custom_message"`
|
||||||
|
SkipMonitoring *bool `json:"skip_monitoring"`
|
||||||
Description *string `json:"description"`
|
Description *string `json:"description"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,6 +124,9 @@ func (h *ErrorPassthroughHandler) Create(c *gin.Context) {
|
|||||||
} else {
|
} else {
|
||||||
rule.PassthroughBody = true
|
rule.PassthroughBody = true
|
||||||
}
|
}
|
||||||
|
if req.SkipMonitoring != nil {
|
||||||
|
rule.SkipMonitoring = *req.SkipMonitoring
|
||||||
|
}
|
||||||
rule.ResponseCode = req.ResponseCode
|
rule.ResponseCode = req.ResponseCode
|
||||||
rule.CustomMessage = req.CustomMessage
|
rule.CustomMessage = req.CustomMessage
|
||||||
rule.Description = req.Description
|
rule.Description = req.Description
|
||||||
@@ -190,6 +195,7 @@ func (h *ErrorPassthroughHandler) Update(c *gin.Context) {
|
|||||||
ResponseCode: existing.ResponseCode,
|
ResponseCode: existing.ResponseCode,
|
||||||
PassthroughBody: existing.PassthroughBody,
|
PassthroughBody: existing.PassthroughBody,
|
||||||
CustomMessage: existing.CustomMessage,
|
CustomMessage: existing.CustomMessage,
|
||||||
|
SkipMonitoring: existing.SkipMonitoring,
|
||||||
Description: existing.Description,
|
Description: existing.Description,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -230,6 +236,9 @@ func (h *ErrorPassthroughHandler) Update(c *gin.Context) {
|
|||||||
if req.Description != nil {
|
if req.Description != nil {
|
||||||
rule.Description = req.Description
|
rule.Description = req.Description
|
||||||
}
|
}
|
||||||
|
if req.SkipMonitoring != nil {
|
||||||
|
rule.SkipMonitoring = *req.SkipMonitoring
|
||||||
|
}
|
||||||
|
|
||||||
// 确保切片不为 nil
|
// 确保切片不为 nil
|
||||||
if rule.ErrorCodes == nil {
|
if rule.ErrorCodes == nil {
|
||||||
|
|||||||
@@ -544,6 +544,13 @@ func OpsErrorLoggerMiddleware(ops *service.OpsService) gin.HandlerFunc {
|
|||||||
body := w.buf.Bytes()
|
body := w.buf.Bytes()
|
||||||
parsed := parseOpsErrorResponse(body)
|
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
|
// 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) {
|
if shouldSkipOpsErrorLog(c.Request.Context(), ops, parsed.Message, string(body), c.Request.URL.Path) {
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ type ErrorPassthroughRule struct {
|
|||||||
ResponseCode *int `json:"response_code"` // 自定义状态码(passthrough_code=false 时使用)
|
ResponseCode *int `json:"response_code"` // 自定义状态码(passthrough_code=false 时使用)
|
||||||
PassthroughBody bool `json:"passthrough_body"` // 是否透传原始错误信息
|
PassthroughBody bool `json:"passthrough_body"` // 是否透传原始错误信息
|
||||||
CustomMessage *string `json:"custom_message"` // 自定义错误信息(passthrough_body=false 时使用)
|
CustomMessage *string `json:"custom_message"` // 自定义错误信息(passthrough_body=false 时使用)
|
||||||
|
SkipMonitoring bool `json:"skip_monitoring"` // 是否跳过运维监控记录
|
||||||
Description *string `json:"description"` // 规则描述
|
Description *string `json:"description"` // 规则描述
|
||||||
CreatedAt time.Time `json:"created_at"`
|
CreatedAt time.Time `json:"created_at"`
|
||||||
UpdatedAt time.Time `json:"updated_at"`
|
UpdatedAt time.Time `json:"updated_at"`
|
||||||
|
|||||||
@@ -54,7 +54,8 @@ func (r *errorPassthroughRepository) Create(ctx context.Context, rule *model.Err
|
|||||||
SetPriority(rule.Priority).
|
SetPriority(rule.Priority).
|
||||||
SetMatchMode(rule.MatchMode).
|
SetMatchMode(rule.MatchMode).
|
||||||
SetPassthroughCode(rule.PassthroughCode).
|
SetPassthroughCode(rule.PassthroughCode).
|
||||||
SetPassthroughBody(rule.PassthroughBody)
|
SetPassthroughBody(rule.PassthroughBody).
|
||||||
|
SetSkipMonitoring(rule.SkipMonitoring)
|
||||||
|
|
||||||
if len(rule.ErrorCodes) > 0 {
|
if len(rule.ErrorCodes) > 0 {
|
||||||
builder.SetErrorCodes(rule.ErrorCodes)
|
builder.SetErrorCodes(rule.ErrorCodes)
|
||||||
@@ -90,7 +91,8 @@ func (r *errorPassthroughRepository) Update(ctx context.Context, rule *model.Err
|
|||||||
SetPriority(rule.Priority).
|
SetPriority(rule.Priority).
|
||||||
SetMatchMode(rule.MatchMode).
|
SetMatchMode(rule.MatchMode).
|
||||||
SetPassthroughCode(rule.PassthroughCode).
|
SetPassthroughCode(rule.PassthroughCode).
|
||||||
SetPassthroughBody(rule.PassthroughBody)
|
SetPassthroughBody(rule.PassthroughBody).
|
||||||
|
SetSkipMonitoring(rule.SkipMonitoring)
|
||||||
|
|
||||||
// 处理可选字段
|
// 处理可选字段
|
||||||
if len(rule.ErrorCodes) > 0 {
|
if len(rule.ErrorCodes) > 0 {
|
||||||
@@ -149,6 +151,7 @@ func (r *errorPassthroughRepository) toModel(e *ent.ErrorPassthroughRule) *model
|
|||||||
Platforms: e.Platforms,
|
Platforms: e.Platforms,
|
||||||
PassthroughCode: e.PassthroughCode,
|
PassthroughCode: e.PassthroughCode,
|
||||||
PassthroughBody: e.PassthroughBody,
|
PassthroughBody: e.PassthroughBody,
|
||||||
|
SkipMonitoring: e.SkipMonitoring,
|
||||||
CreatedAt: e.CreatedAt,
|
CreatedAt: e.CreatedAt,
|
||||||
UpdatedAt: e.UpdatedAt,
|
UpdatedAt: e.UpdatedAt,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,6 +61,11 @@ func applyErrorPassthroughRule(
|
|||||||
errMsg = *rule.CustomMessage
|
errMsg = *rule.CustomMessage
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 命中 skip_monitoring 时在 context 中标记,供 ops_error_logger 跳过记录。
|
||||||
|
if rule.SkipMonitoring {
|
||||||
|
c.Set(OpsSkipPassthroughKey, true)
|
||||||
|
}
|
||||||
|
|
||||||
// 与现有 failover 场景保持一致:命中规则时统一返回 upstream_error。
|
// 与现有 failover 场景保持一致:命中规则时统一返回 upstream_error。
|
||||||
errType = "upstream_error"
|
errType = "upstream_error"
|
||||||
return status, errType, errMsg, true
|
return status, errType, errMsg, true
|
||||||
|
|||||||
@@ -194,6 +194,61 @@ func TestGeminiWriteGeminiMappedError_AppliesRuleFor422(t *testing.T) {
|
|||||||
assert.Equal(t, "Gemini上游失败", errField["message"])
|
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 {
|
func newNonFailoverPassthroughRule(statusCode int, keyword string, respCode int, customMessage string) *model.ErrorPassthroughRule {
|
||||||
return &model.ErrorPassthroughRule{
|
return &model.ErrorPassthroughRule{
|
||||||
ID: 1,
|
ID: 1,
|
||||||
|
|||||||
@@ -20,6 +20,10 @@ const (
|
|||||||
// retry the specific upstream attempt (not just the client request).
|
// retry the specific upstream attempt (not just the client request).
|
||||||
// This value is sanitized+trimmed before being persisted.
|
// This value is sanitized+trimmed before being persisted.
|
||||||
OpsUpstreamRequestBodyKey = "ops_upstream_request_body"
|
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) {
|
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
|
response_code: number | null
|
||||||
passthrough_body: boolean
|
passthrough_body: boolean
|
||||||
custom_message: string | null
|
custom_message: string | null
|
||||||
|
skip_monitoring: boolean
|
||||||
description: string | null
|
description: string | null
|
||||||
created_at: string
|
created_at: string
|
||||||
updated_at: string
|
updated_at: string
|
||||||
@@ -41,6 +42,7 @@ export interface CreateRuleRequest {
|
|||||||
response_code?: number | null
|
response_code?: number | null
|
||||||
passthrough_body?: boolean
|
passthrough_body?: boolean
|
||||||
custom_message?: string | null
|
custom_message?: string | null
|
||||||
|
skip_monitoring?: boolean
|
||||||
description?: string | null
|
description?: string | null
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,6 +61,7 @@ export interface UpdateRuleRequest {
|
|||||||
response_code?: number | null
|
response_code?: number | null
|
||||||
passthrough_body?: boolean
|
passthrough_body?: boolean
|
||||||
custom_message?: string | null
|
custom_message?: string | null
|
||||||
|
skip_monitoring?: boolean
|
||||||
description?: string | null
|
description?: string | null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -148,6 +148,16 @@
|
|||||||
{{ rule.passthrough_body ? t('admin.errorPassthrough.passthrough') : t('admin.errorPassthrough.custom') }}
|
{{ rule.passthrough_body ? t('admin.errorPassthrough.passthrough') : t('admin.errorPassthrough.custom') }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</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>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="px-3 py-2">
|
<td class="px-3 py-2">
|
||||||
@@ -366,6 +376,19 @@
|
|||||||
</div>
|
</div>
|
||||||
</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 -->
|
<!-- Enabled -->
|
||||||
<div class="flex items-center gap-1.5">
|
<div class="flex items-center gap-1.5">
|
||||||
<input
|
<input
|
||||||
@@ -453,6 +476,7 @@ const form = reactive({
|
|||||||
response_code: null as number | null,
|
response_code: null as number | null,
|
||||||
passthrough_body: true,
|
passthrough_body: true,
|
||||||
custom_message: null as string | null,
|
custom_message: null as string | null,
|
||||||
|
skip_monitoring: false,
|
||||||
description: null as string | null
|
description: null as string | null
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -497,6 +521,7 @@ const resetForm = () => {
|
|||||||
form.response_code = null
|
form.response_code = null
|
||||||
form.passthrough_body = true
|
form.passthrough_body = true
|
||||||
form.custom_message = null
|
form.custom_message = null
|
||||||
|
form.skip_monitoring = false
|
||||||
form.description = null
|
form.description = null
|
||||||
errorCodesInput.value = ''
|
errorCodesInput.value = ''
|
||||||
keywordsInput.value = ''
|
keywordsInput.value = ''
|
||||||
@@ -520,6 +545,7 @@ const handleEdit = (rule: ErrorPassthroughRule) => {
|
|||||||
form.response_code = rule.response_code
|
form.response_code = rule.response_code
|
||||||
form.passthrough_body = rule.passthrough_body
|
form.passthrough_body = rule.passthrough_body
|
||||||
form.custom_message = rule.custom_message
|
form.custom_message = rule.custom_message
|
||||||
|
form.skip_monitoring = rule.skip_monitoring
|
||||||
form.description = rule.description
|
form.description = rule.description
|
||||||
errorCodesInput.value = rule.error_codes.join(', ')
|
errorCodesInput.value = rule.error_codes.join(', ')
|
||||||
keywordsInput.value = rule.keywords.join('\n')
|
keywordsInput.value = rule.keywords.join('\n')
|
||||||
@@ -575,6 +601,7 @@ const handleSubmit = async () => {
|
|||||||
response_code: form.passthrough_code ? null : form.response_code,
|
response_code: form.passthrough_code ? null : form.response_code,
|
||||||
passthrough_body: form.passthrough_body,
|
passthrough_body: form.passthrough_body,
|
||||||
custom_message: form.passthrough_body ? null : form.custom_message,
|
custom_message: form.passthrough_body ? null : form.custom_message,
|
||||||
|
skip_monitoring: form.skip_monitoring,
|
||||||
description: form.description?.trim() || null
|
description: form.description?.trim() || null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3353,6 +3353,7 @@ export default {
|
|||||||
custom: 'Custom',
|
custom: 'Custom',
|
||||||
code: 'Code',
|
code: 'Code',
|
||||||
body: 'Body',
|
body: 'Body',
|
||||||
|
skipMonitoring: 'Skip Monitoring',
|
||||||
|
|
||||||
// Columns
|
// Columns
|
||||||
columns: {
|
columns: {
|
||||||
@@ -3397,6 +3398,8 @@ export default {
|
|||||||
passthroughBody: 'Passthrough upstream error message',
|
passthroughBody: 'Passthrough upstream error message',
|
||||||
customMessage: 'Custom error message',
|
customMessage: 'Custom error message',
|
||||||
customMessagePlaceholder: 'Error message to return to client...',
|
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'
|
enabled: 'Enable this rule'
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -3527,6 +3527,7 @@ export default {
|
|||||||
custom: '自定义',
|
custom: '自定义',
|
||||||
code: '状态码',
|
code: '状态码',
|
||||||
body: '消息体',
|
body: '消息体',
|
||||||
|
skipMonitoring: '跳过监控',
|
||||||
|
|
||||||
// Columns
|
// Columns
|
||||||
columns: {
|
columns: {
|
||||||
@@ -3571,6 +3572,8 @@ export default {
|
|||||||
passthroughBody: '透传上游错误信息',
|
passthroughBody: '透传上游错误信息',
|
||||||
customMessage: '自定义错误信息',
|
customMessage: '自定义错误信息',
|
||||||
customMessagePlaceholder: '返回给客户端的错误信息...',
|
customMessagePlaceholder: '返回给客户端的错误信息...',
|
||||||
|
skipMonitoring: '跳过运维监控记录',
|
||||||
|
skipMonitoringHint: '开启后,匹配此规则的错误不会被记录到运维监控中',
|
||||||
enabled: '启用此规则'
|
enabled: '启用此规则'
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user