| 
									
										
										
										
											2020-11-12 19:29:43 +08:00
										 |  |  | package api | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2021-11-29 17:18:01 +08:00
										 |  |  | 	"net/http" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-12 19:29:43 +08:00
										 |  |  | 	"github.com/getsentry/sentry-go" | 
					
						
							| 
									
										
										
										
											2021-02-04 14:37:28 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/api/frontendlogging" | 
					
						
							| 
									
										
										
										
											2021-01-15 21:43:20 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/api/response" | 
					
						
							| 
									
										
										
										
											2020-11-12 19:29:43 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/infra/log" | 
					
						
							|  |  |  | 	"github.com/grafana/grafana/pkg/models" | 
					
						
							| 
									
										
										
										
											2021-11-29 17:18:01 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/web" | 
					
						
							| 
									
										
										
										
											2020-11-12 19:29:43 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var frontendLogger = log.New("frontend") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-29 17:18:01 +08:00
										 |  |  | type frontendLogMessageHandler func(c *models.ReqContext) response.Response | 
					
						
							| 
									
										
										
										
											2020-11-12 19:29:43 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-04 14:37:28 +08:00
										 |  |  | func NewFrontendLogMessageHandler(store *frontendlogging.SourceMapStore) frontendLogMessageHandler { | 
					
						
							| 
									
										
										
										
											2021-11-29 17:18:01 +08:00
										 |  |  | 	return func(c *models.ReqContext) response.Response { | 
					
						
							|  |  |  | 		event := frontendlogging.FrontendSentryEvent{} | 
					
						
							|  |  |  | 		if err := web.Bind(c.Req, &event); err != nil { | 
					
						
							|  |  |  | 			return response.Error(http.StatusBadRequest, "bad request data", err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-04 14:37:28 +08:00
										 |  |  | 		var msg = "unknown" | 
					
						
							| 
									
										
										
										
											2020-11-12 19:29:43 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-04 14:37:28 +08:00
										 |  |  | 		if len(event.Message) > 0 { | 
					
						
							|  |  |  | 			msg = event.Message | 
					
						
							|  |  |  | 		} else if event.Exception != nil && len(event.Exception.Values) > 0 { | 
					
						
							|  |  |  | 			msg = event.Exception.Values[0].FmtMessage() | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-11-12 19:29:43 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-04 14:37:28 +08:00
										 |  |  | 		var ctx = event.ToLogContext(store) | 
					
						
							| 
									
										
										
										
											2020-11-12 19:29:43 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-04 14:37:28 +08:00
										 |  |  | 		switch event.Level { | 
					
						
							|  |  |  | 		case sentry.LevelError: | 
					
						
							| 
									
										
										
										
											2022-01-06 22:28:05 +08:00
										 |  |  | 			frontendLogger.Error(msg, ctx...) | 
					
						
							| 
									
										
										
										
											2021-02-04 14:37:28 +08:00
										 |  |  | 		case sentry.LevelWarning: | 
					
						
							| 
									
										
										
										
											2022-01-06 22:28:05 +08:00
										 |  |  | 			frontendLogger.Warn(msg, ctx...) | 
					
						
							| 
									
										
										
										
											2021-02-04 14:37:28 +08:00
										 |  |  | 		case sentry.LevelDebug: | 
					
						
							| 
									
										
										
										
											2022-01-06 22:28:05 +08:00
										 |  |  | 			frontendLogger.Debug(msg, ctx...) | 
					
						
							| 
									
										
										
										
											2020-12-10 17:50:37 +08:00
										 |  |  | 		default: | 
					
						
							| 
									
										
										
										
											2022-01-06 22:28:05 +08:00
										 |  |  | 			frontendLogger.Info(msg, ctx...) | 
					
						
							| 
									
										
										
										
											2020-12-10 17:50:37 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-11-12 19:29:43 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-04 14:37:28 +08:00
										 |  |  | 		return response.Success("ok") | 
					
						
							| 
									
										
										
										
											2020-11-12 19:29:43 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2022-06-28 15:25:30 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | func GrafanaJavascriptAgentLogMessageHandler(store *frontendlogging.SourceMapStore) frontendLogMessageHandler { | 
					
						
							|  |  |  | 	return func(c *models.ReqContext) response.Response { | 
					
						
							|  |  |  | 		event := frontendlogging.FrontendGrafanaJavascriptAgentEvent{} | 
					
						
							|  |  |  | 		if err := web.Bind(c.Req, &event); err != nil { | 
					
						
							|  |  |  | 			return response.Error(http.StatusBadRequest, "bad request data", err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Meta object is standard across event types, adding it globally.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if event.Logs != nil && len(event.Logs) > 0 { | 
					
						
							|  |  |  | 			for _, logEntry := range event.Logs { | 
					
						
							|  |  |  | 				var ctx = frontendlogging.CtxVector{} | 
					
						
							|  |  |  | 				ctx = event.AddMetaToContext(ctx) | 
					
						
							|  |  |  | 				ctx = append(ctx, "kind", "log", "original_timestamp", logEntry.Timestamp) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				for k, v := range frontendlogging.KeyValToInterfaceMap(logEntry.KeyValContext()) { | 
					
						
							|  |  |  | 					ctx = append(ctx, k, v) | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				switch logEntry.LogLevel { | 
					
						
							|  |  |  | 				case frontendlogging.LogLevelDebug, frontendlogging.LogLevelTrace: | 
					
						
							|  |  |  | 					{ | 
					
						
							|  |  |  | 						ctx = append(ctx, "original_log_level", logEntry.LogLevel) | 
					
						
							|  |  |  | 						frontendLogger.Debug(logEntry.Message, ctx...) | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				case frontendlogging.LogLevelError: | 
					
						
							|  |  |  | 					{ | 
					
						
							|  |  |  | 						ctx = append(ctx, "original_log_level", logEntry.LogLevel) | 
					
						
							|  |  |  | 						frontendLogger.Error(logEntry.Message, ctx...) | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				case frontendlogging.LogLevelWarning: | 
					
						
							|  |  |  | 					{ | 
					
						
							|  |  |  | 						ctx = append(ctx, "original_log_level", logEntry.LogLevel) | 
					
						
							|  |  |  | 						frontendLogger.Warn(logEntry.Message, ctx...) | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				default: | 
					
						
							|  |  |  | 					{ | 
					
						
							|  |  |  | 						ctx = append(ctx, "original_log_level", logEntry.LogLevel) | 
					
						
							|  |  |  | 						frontendLogger.Info(logEntry.Message, ctx...) | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if event.Measurements != nil && len(event.Measurements) > 0 { | 
					
						
							|  |  |  | 			for _, measurementEntry := range event.Measurements { | 
					
						
							|  |  |  | 				for measurementName, measurementValue := range measurementEntry.Values { | 
					
						
							|  |  |  | 					var ctx = frontendlogging.CtxVector{} | 
					
						
							|  |  |  | 					ctx = event.AddMetaToContext(ctx) | 
					
						
							|  |  |  | 					ctx = append(ctx, measurementName, measurementValue) | 
					
						
							|  |  |  | 					ctx = append(ctx, "kind", "measurement", "original_timestamp", measurementEntry.Timestamp) | 
					
						
							|  |  |  | 					frontendLogger.Info("Measurement: "+measurementEntry.Type, ctx...) | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if event.Exceptions != nil && len(event.Exceptions) > 0 { | 
					
						
							|  |  |  | 			for _, exception := range event.Exceptions { | 
					
						
							|  |  |  | 				var ctx = frontendlogging.CtxVector{} | 
					
						
							|  |  |  | 				ctx = event.AddMetaToContext(ctx) | 
					
						
							|  |  |  | 				exception := exception | 
					
						
							|  |  |  | 				transformedException := frontendlogging.TransformException(&exception, store) | 
					
						
							|  |  |  | 				ctx = append(ctx, "kind", "exception", "type", transformedException.Type, "value", transformedException.Value, "stacktrace", transformedException.String()) | 
					
						
							|  |  |  | 				ctx = append(ctx, "original_timestamp", exception.Timestamp) | 
					
						
							|  |  |  | 				frontendLogger.Error(exception.Message(), ctx...) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return response.Success("ok") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } |