Skip to content

Commit

Permalink
fix(common): support report bug (#18626)
Browse files Browse the repository at this point in the history
  • Loading branch information
ioito authored Nov 10, 2023
1 parent 6621e3f commit f52e78a
Show file tree
Hide file tree
Showing 12 changed files with 232 additions and 2 deletions.
47 changes: 47 additions & 0 deletions cmd/climc/shell/yunionconf/bugreport.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package yunionconf

import (
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/mcclient/modules/yunionconf"
)

func init() {
type BugReportStatusOptions struct {
}

R(&BugReportStatusOptions{}, "bug-report-status", "Show bug report status", func(s *mcclient.ClientSession, args *BugReportStatusOptions) error {
ret, err := yunionconf.BugReport.GetBugReportEnabled(s, nil)
if err != nil {
return err
}
printObject(ret)
return nil
})

type BugReportEnableOptions struct {
}

R(&BugReportEnableOptions{}, "bug-report-enable", "Enable bug report", func(s *mcclient.ClientSession, args *BugReportEnableOptions) error {
ret, err := yunionconf.BugReport.DoBugReportEnable(s, nil)
if err != nil {
return err
}
printObject(ret)
return nil
})

}
4 changes: 4 additions & 0 deletions pkg/baremetal/tasks/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,13 @@ import (

"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/version"

"yunion.io/x/onecloud/pkg/appsrv"
"yunion.io/x/onecloud/pkg/baremetal/options"
modules "yunion.io/x/onecloud/pkg/mcclient/modules/compute"
"yunion.io/x/onecloud/pkg/mcclient/modules/yunionconf"
)

var baremetalTaskWorkerMan *appsrv.SWorkerManager
Expand Down Expand Up @@ -78,6 +81,7 @@ func executeTask(task ITask, args interface{}) {
log.Errorf("Execute task panic: %v", err)
debug.PrintStack()
SetTaskFail(task, fmt.Errorf("%v", err))
yunionconf.BugReport.SendBugReport(context.Background(), version.GetShortString(), string(debug.Stack()), errors.Errorf("%s", err))
}
}()
err := curStage(context.Background(), args)
Expand Down
3 changes: 3 additions & 0 deletions pkg/cloudcommon/cronman/cronman.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,14 @@ import (
"yunion.io/x/log"
"yunion.io/x/pkg/appctx"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/version"

"yunion.io/x/onecloud/pkg/appsrv"
"yunion.io/x/onecloud/pkg/cloudcommon/consts"
"yunion.io/x/onecloud/pkg/cloudcommon/elect"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/mcclient/auth"
"yunion.io/x/onecloud/pkg/mcclient/modules/yunionconf"
)

var (
Expand Down Expand Up @@ -444,6 +446,7 @@ func (job *SCronJob) runJobInWorker(isStart bool, startTime time.Time) {
if r := recover(); r != nil {
log.Errorf("CronJob task %s run error: %s", job.Name, r)
debug.PrintStack()
yunionconf.BugReport.SendBugReport(context.Background(), version.GetShortString(), string(debug.Stack()), errors.Errorf("%s", r))
}
}()

Expand Down
5 changes: 5 additions & 0 deletions pkg/cloudcommon/db/taskman/localtaskworker.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,17 @@
package taskman

import (
"context"
"fmt"
"runtime/debug"

"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/version"

"yunion.io/x/onecloud/pkg/appsrv"
"yunion.io/x/onecloud/pkg/mcclient/modules/yunionconf"
)

var localTaskWorkerMan *appsrv.SWorkerManager
Expand All @@ -48,6 +52,7 @@ func (t *localTask) Run() {

defer func() {
if r := recover(); r != nil {
yunionconf.BugReport.SendBugReport(context.Background(), version.GetShortString(), string(debug.Stack()), errors.Errorf("%s", r))
log.Errorf("LocalTaskRun error: %s", r)
debug.PrintStack()
t.task.ScheduleRun(Error2TaskData(fmt.Errorf("LocalTaskRun error: %s", r)))
Expand Down
2 changes: 2 additions & 0 deletions pkg/cloudcommon/db/taskman/tasks.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import (
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/mcclient/auth"
"yunion.io/x/onecloud/pkg/mcclient/modules/yunionconf"
"yunion.io/x/onecloud/pkg/util/logclient"
)

Expand Down Expand Up @@ -544,6 +545,7 @@ func execITask(taskValue reflect.Value, task *STask, odata jsonutils.JSONObject,
if r := recover(); r != nil {
// call set stage failed, should not call task.SetStageFailed
// func SetStageFailed may be overloading
yunionconf.BugReport.SendBugReport(ctx, version.GetShortString(), string(debug.Stack()), errors.Errorf("%s", r))
log.Errorf("Task %s PANIC on stage %s: %v \n%s", task.TaskName, stageName, r, debug.Stack())
SetStageFailedFuncValue := taskValue.MethodByName("SetStageFailed")
SetStageFailedFuncValue.Call(
Expand Down
5 changes: 5 additions & 0 deletions pkg/cloudcommon/workmanager/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,11 @@ import (
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/appctx"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/version"

"yunion.io/x/onecloud/pkg/appsrv"
"yunion.io/x/onecloud/pkg/mcclient/modules/yunionconf"
)

type DelayTaskFunc func(context.Context, interface{}) (jsonutils.JSONObject, error)
Expand Down Expand Up @@ -69,6 +72,7 @@ func (t *workerTask) Run() {
defer func() {
if r := recover(); r != nil {
log.Errorf("DelayTask panic: %s", r)
yunionconf.BugReport.SendBugReport(t.ctx, version.GetShortString(), string(debug.Stack()), errors.Errorf("%s", r))
debug.PrintStack()
switch val := r.(type) {
case string:
Expand Down Expand Up @@ -139,6 +143,7 @@ func (t *delayWorkerTask) Run() {
if r := recover(); r != nil {
log.Errorln("DelayTaskWithoutReqctx panic: ", r)
debug.PrintStack()
yunionconf.BugReport.SendBugReport(t.ctx, version.GetShortString(), string(debug.Stack()), errors.Errorf("%s", r))
}
}()

Expand Down
3 changes: 3 additions & 0 deletions pkg/cloudproxy/agent/worker/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (

"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/version"
"yunion.io/x/pkg/utils"

"yunion.io/x/onecloud/pkg/apihelper"
Expand All @@ -35,6 +36,7 @@ import (
agentssh "yunion.io/x/onecloud/pkg/cloudproxy/agent/ssh"
"yunion.io/x/onecloud/pkg/mcclient/auth"
cloudproxy_modules "yunion.io/x/onecloud/pkg/mcclient/modules/cloudproxy"
"yunion.io/x/onecloud/pkg/mcclient/modules/yunionconf"
"yunion.io/x/onecloud/pkg/util/netutils2"
ssh_util "yunion.io/x/onecloud/pkg/util/ssh"
)
Expand Down Expand Up @@ -207,6 +209,7 @@ func (w *Worker) Start(ctx context.Context) {
func (w *Worker) run(ctx context.Context, mss *agentmodels.ModelSets) (err error) {
defer func() {
if panicVal := recover(); panicVal != nil {
yunionconf.BugReport.SendBugReport(context.Background(), version.GetShortString(), string(debug.Stack()), errors.Errorf("%s", panicVal))
if panicErr, ok := panicVal.(runtime.Error); ok {
err = errors.Wrap(panicErr, string(debug.Stack()))
} else if panicErr, ok := panicVal.(error); ok {
Expand Down
4 changes: 4 additions & 0 deletions pkg/compute/models/syncworkers.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,12 @@ import (

"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/util/version"

api "yunion.io/x/onecloud/pkg/apis/notify"
"yunion.io/x/onecloud/pkg/appsrv"
"yunion.io/x/onecloud/pkg/cloudcommon/notifyclient"
"yunion.io/x/onecloud/pkg/mcclient/modules/yunionconf"
)

var (
Expand Down Expand Up @@ -85,6 +87,7 @@ func RunSyncCloudproviderRegionTask(ctx context.Context, key string, syncFunc fu
data.Add(jsonutils.NewString(string(debug.Stack())), "stack")
data.Add(jsonutils.NewString(err.Error()), "error")
notifyclient.SystemExceptionNotify(context.TODO(), api.ActionSystemPanic, api.TOPIC_RESOURCE_TASK, data)
yunionconf.BugReport.SendBugReport(ctx, version.GetShortString(), string(debug.Stack()), err)
})
}

Expand All @@ -100,5 +103,6 @@ func RunSyncCloudAccountTask(ctx context.Context, probeFunc func()) {
data.Add(jsonutils.NewString(string(debug.Stack())), "stack")
data.Add(jsonutils.NewString(err.Error()), "error")
notifyclient.SystemExceptionNotify(context.TODO(), api.ActionSystemPanic, api.TOPIC_RESOURCE_TASK, data)
yunionconf.BugReport.SendBugReport(ctx, version.GetShortString(), string(debug.Stack()), err)
})
}
60 changes: 60 additions & 0 deletions pkg/mcclient/modules/yunionconf/mod_bugreport.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package yunionconf

import (
"context"

"yunion.io/x/jsonutils"

"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/mcclient/auth"
"yunion.io/x/onecloud/pkg/mcclient/modulebase"
"yunion.io/x/onecloud/pkg/mcclient/modules"
)

type BugReportManager struct {
modulebase.ResourceManager
}

var (
BugReport BugReportManager
)

func init() {
BugReport = BugReportManager{modules.NewYunionConfManager("bug-report", "bug-report",
[]string{},
[]string{},
)}
modules.Register(&BugReport)
}

func (m BugReportManager) DoBugReportEnable(s *mcclient.ClientSession, _ jsonutils.JSONObject) (jsonutils.JSONObject, error) {
return modulebase.Post(m.ResourceManager, s, "enable-bug-report", nil, "")
}

func (m BugReportManager) GetBugReportEnabled(s *mcclient.ClientSession, params jsonutils.JSONObject) (jsonutils.JSONObject, error) {
return modulebase.Get(m.ResourceManager, s, "bug-report-status", "")
}

func (m BugReportManager) SendBugReport(ctx context.Context, version, stack string, err error) (jsonutils.JSONObject, error) {
msg := map[string]interface{}{
"version": version,
"stack": stack,
"message": err.Error(),
}
s := auth.GetAdminSession(ctx, "")
return modulebase.Post(m.ResourceManager, s, "send-bug-report", jsonutils.Marshal(msg), "")
}
7 changes: 7 additions & 0 deletions pkg/util/atexit/atexit.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,16 @@
package atexit

import (
"context"
"os"
"runtime/debug"
"sort"
"sync"

"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/version"

"yunion.io/x/onecloud/pkg/mcclient/modules/yunionconf"
)

// ExitHandlerFunc is the type of handler func
Expand Down Expand Up @@ -95,6 +101,7 @@ func Handle() {
if val != nil {
print("panic ", val, "\n")
debug.PrintStack()
yunionconf.BugReport.SendBugReport(context.Background(), version.GetShortString(), string(debug.Stack()), errors.Errorf("%s", val))
}
}()
eh.Func(eh)
Expand Down
37 changes: 35 additions & 2 deletions pkg/yunionconf/models/parameters.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,9 @@ import (
)

const (
NAMESPACE_USER = "user"
NAMESPACE_SERVICE = "service"
NAMESPACE_USER = "user"
NAMESPACE_SERVICE = "service"
NAMESPACE_BUG_REPORT = "bug-report"
)

type SParameterManager struct {
Expand Down Expand Up @@ -364,3 +365,35 @@ func (model *SParameter) GetId() string {
func (model *SParameter) GetName() string {
return model.Name
}

var bugReportEnable *bool = nil

func (manager *SParameterManager) GetBugReportEnabled() bool {
if bugReportEnable != nil {
return *bugReportEnable
}
enabled := manager.Query().Equals("namespace", NAMESPACE_BUG_REPORT).Count() > 0
bugReportEnable = &enabled
return enabled
}

func (manager *SParameterManager) EnableBugReport(ctx context.Context) bool {
if manager.GetBugReportEnabled() {
return true
}
res := &SParameter{
Namespace: NAMESPACE_BUG_REPORT,
NamespaceId: NAMESPACE_BUG_REPORT,
Name: NAMESPACE_BUG_REPORT,
Value: jsonutils.NewDict(),
CreatedBy: api.SERVICE_TYPE,
}
res.SetModelManager(manager, res)
err := manager.TableSpec().Insert(ctx, res)
if err != nil {
return false
}
enabled := true
bugReportEnable = &enabled
return true
}
Loading

0 comments on commit f52e78a

Please sign in to comment.