Ejemplo n.º 1
0
        public static ErrorReporter.OnError createSendOnError(
            string loggerName, Uri reportingUrl, ApiKeys keys, ErrorReporter.AppInfo appInfo,
            ExtraData addExtraData, bool onlySendUniqueErrors
            )
        {
            var sentJsonsOpt = onlySendUniqueErrors.opt(() => new HashSet <string>());

            return(data => {
                var msg = message(loggerName, keys, appInfo, data, addExtraData);
                Action send = () => ASync.NextFrame(() => msg.send(reportingUrl));
                sentJsonsOpt.voidFold(
                    send,
                    sentJsons => {
                    if (sentJsons.Add(msg.json))
                    {
                        send();
                    }
                    else if (Log.isDebug)
                    {
                        Log.rdebug($"Not sending duplicate Sentry msg: {msg}");
                    }
                }
                    );
            });
        }
Ejemplo n.º 2
0
        public static Message message(
            SentryAPI.ApiKeys keys, ErrorReporter.AppInfo appInfo,
            LogEvent data, SentryAPI.ExtraData extraData, Option <SentryAPI.UserInterface> userOpt,
            IDictionary <string, SentryAPI.Tag> staticTags
            )
        {
            const string logger    = "tlplib-" + nameof(SentryRESTAPI);
            var          eventId   = Guid.NewGuid();
            var          timestamp = DateTime.UtcNow;

            // The list of frames should be ordered by the oldest call first.
            var stacktraceFrames = data.entry.backtrace.map(
                // ReSharper disable once ConvertClosureToMethodGroup - MCS bug
                b => b.elements.a.Select(a => backtraceElemToJson(a)).Reverse().ToList()
                );

            // Beware of the order! Do not mutate static tags!
            var tags =
                SentryAPI.dynamicTags()
                .addAll(staticTags)
                .addAll(SentryAPI.convertTags(data.entry.tags));

            extraData.addTagsToDictionary(tags);

            // Extra contextual data is limited to 4096 characters.
            var extras =
                SentryAPI.dynamicExtras()
                .addAll(SentryAPI.convertExtras(data.entry.extras));

            extraData.addExtrasToDictionary(extras);

            var json = new Dictionary <string, object> {
                { "message", s(data.entry.message) },
                { "level", s(data.level.asSentry(), SentryAPI.LogLevel_.str) },
                { "logger", s(logger) },
                { "platform", s(Application.platform.ToString()) },
                { "release", s(appInfo.bundleVersion) },
                { "tags", tags.toDict(_ => _.Key, _ => _.Value.s) },
                { "extra", extras },
                { "fingerprint", data.entry.toSentryFingerprint() }
            };

            foreach (var stacktrace in stacktraceFrames)
            {
                json.Add("stacktrace", new Dictionary <string, object> {
                    { "frames", stacktrace }
                });
            }
            foreach (var user in userOpt)
            {
                json.Add("user", userInterfaceParametersJson(user));
            }

            return(new Message(keys, eventId, timestamp, json));
        }
Ejemplo n.º 3
0
 public static ErrorReporter.OnError createEditorOnError(
     string apiKey, ErrorReporter.AppInfo appInfo
     )
 {
     return(data => ASync.NextFrame(() => {
         if (Log.isInfo)
         {
             Log.info("Airbrake error:\n\n" + data + "\n" + xml(apiKey, appInfo, data));
         }
     }));
 }
Ejemplo n.º 4
0
 public SendOnErrorData(
     ErrorReporter.AppInfo appInfo, ExtraData addExtraData,
     Option <UserInterface> userOpt,
     IDictionary <string, Tag> staticTags, IDictionary <string, string> staticExtras
     )
 {
     this.appInfo      = appInfo;
     this.addExtraData = addExtraData;
     this.userOpt      = userOpt;
     this.staticTags   = staticTags;
     this.staticExtras = staticExtras;
 }
Ejemplo n.º 5
0
        public static AirbrakeXML xml(
            string apiKey, ErrorReporter.AppInfo appInfo, ErrorReporter.ErrorData data
            )
        {
            var doc = new XmlDocument();
            var dec = doc.CreateXmlDeclaration("1.0", "UTF-8", null);

            doc.AppendChild(dec);

            // Required. The version of the API being used. Should be set to "2.3"
            var root = doc.CreateElement("notice");

            doc.AppendChild(root);
            root.SetAttribute("version", "2.3");

            // Required. The API key for the project that this error belongs to.
            // The API key can be found by viewing the edit project form on the Airbrake site.
            root.AppendChild(doc.textElem("api-key", apiKey));

            root.AppendChild(doc.CreateElement("notifier")).tap(notifier => {
                notifier.AppendChild(doc.textElem("name", "tlplib"));
                notifier.AppendChild(doc.textElem("version", "1.0"));
                notifier.AppendChild(doc.textElem("url", "https://github.com/tinylabproductions/tlplib"));
            });

            root.AppendChild(doc.CreateElement("server-environment").tap(env => {
                env.AppendChild(doc.textElem(
                                    "environment-name", Debug.isDebugBuild ? "debug" : "production"
                                    ));
                env.AppendChild(doc.textElem("app-version", appInfo.bundleVersion.asString));
            }));

            root.AppendChild(doc.CreateElement("error").tap(err => {
                err.AppendChild(doc.textElem("class", data.errorType.ToString()));
                err.AppendChild(doc.textElem("message", data.message));
                err.AppendChild(doc.CreateElement("backtrace").tap(xmlBt => {
                    foreach (var btElem in data.backtrace)
                    {
                        xmlBt.AppendChild(doc.backtraceElem(btElem));
                    }
                }));
            }));

            root.AppendChild(doc.CreateElement("request").tap(req => {
                req.AppendChild(doc.textElem("url", appInfo.bundleIdentifier));
                req.AppendChild(doc.textElem("component", ""));
            }));

            return(new AirbrakeXML(doc));
        }
Ejemplo n.º 6
0
 public static ErrorReporter.OnError createLogOnError(
     string loggerName, DSN dsn, ErrorReporter.AppInfo appInfo,
     ExtraData addExtraData
     )
 {
     return(data => ASync.NextFrame(() => {
         if (Log.isInfo)
         {
             Log.info(
                 $"Sentry error:\n\n{data}\nreporting url={dsn.reportingUrl}\n" +
                 message(loggerName, dsn.keys, appInfo, data, addExtraData)
                 );
         }
     }));
 }
Ejemplo n.º 7
0
 /// <summary>Tags that will never change during runtime.</summary>
 public static Dictionary <string, Tag> staticTags(ErrorReporter.AppInfo appInfo) =>
Ejemplo n.º 8
0
        public static SentryMessage message(
            string loggerName, ApiKeys keys, ErrorReporter.AppInfo appInfo,
            ErrorReporter.ErrorData data, ExtraData addExtraData
            )
        {
            var timestamp = DateTime.UtcNow;

            // The list of frames should be ordered by the oldest call first.
            // ReSharper disable once ConvertClosureToMethodGroup - MCS bug
            var stacktraceFrames = data.backtrace.Select(a => backtraceElemToJson(a)).Reverse().ToList();

            // Tags are properties that can be filtered/grouped by.
            var tags = new Dictionary <string, object> {
                // max tag name length = 32
                { "ProductName", tag(appInfo.productName) },
                { "BundleIdentifier", tag(appInfo.bundleIdentifier) },
                { "App:LoadedLevelNames", tag(
                      Enumerable2.fromImperative(SceneManager.sceneCount, SceneManager.GetSceneAt).
                      Select(_ => $"{_.name}({_.buildIndex})").OrderBy(_ => _).mkString(", ")
                      ) },
                { "App:LevelCount", tag(SceneManager.sceneCountInBuildSettings) },
                { "App:Platform", tag(Application.platform) },
                { "App:UnityVersion", tag(Application.unityVersion) },
                { "App:Version", tag(Application.version) },
                { "App:BundleIdentifier", tag(Application.bundleIdentifier) },
                { "App:InstallMode", tag(Application.installMode) },
                { "App:SandboxType", tag(Application.sandboxType) },
                { "App:ProductName", tag(Application.productName) },
                { "App:CompanyName", tag(Application.companyName) },
                { "App:CloudProjectId", tag(Application.cloudProjectId) },
                { "App:WebSecurityEnabled", tag(Application.webSecurityEnabled) },
                { "App:WebSecurityHostUrl", tag(Application.webSecurityHostUrl) },
                { "App:TargetFrameRate", tag(Application.targetFrameRate) },
                { "App:SystemLanguage", tag(Application.systemLanguage) },
                { "App:BackgroundLoadingPriority", tag(Application.backgroundLoadingPriority) },
                { "App:InternetReachability", tag(Application.internetReachability) },
                { "App:GenuineCheckAvailable", tag(Application.genuineCheckAvailable) },
                { "App:Genuine", tag(Application.genuineCheckAvailable && Application.genuine) },
                { "SI:OperatingSystem", tag(SystemInfo.operatingSystem) },
                { "SI:ProcessorType", tag(SystemInfo.processorType) },
                { "SI:ProcessorCount", tag(SystemInfo.processorCount) },
                { "SI:SystemMemorySize", tag(SystemInfo.systemMemorySize) },
                { "SI:GraphicsMemorySize", tag(SystemInfo.graphicsMemorySize) },
                { "SI:GraphicsDeviceName", tag(SystemInfo.graphicsDeviceName) },
                { "SI:GraphicsDeviceVendor", tag(SystemInfo.graphicsDeviceVendor) },
                { "SI:GraphicsDeviceID", tag(SystemInfo.graphicsDeviceID) },
                { "SI:GraphicsDeviceVendorID", tag(SystemInfo.graphicsDeviceVendorID) },
                { "SI:GraphicsDeviceType", tag(SystemInfo.graphicsDeviceType) },
                { "SI:GraphicsDeviceVersion", tag(SystemInfo.graphicsDeviceVersion) },
                { "SI:GraphicsShaderLevel", tag(SystemInfo.graphicsShaderLevel) },
                { "SI:GraphicsMultiThreaded", tag(SystemInfo.graphicsMultiThreaded) },
                { "SI:SupportsShadows", tag(SystemInfo.supportsShadows) },
                { "SI:SupportsRenderTextures", tag(SystemInfo.supportsRenderTextures) },
                { "SI:SupportsRenderToCubemap", tag(SystemInfo.supportsRenderToCubemap) },
                { "SI:SupportsImageEffects", tag(SystemInfo.supportsImageEffects) },
                { "SI:Supports3DTextures", tag(SystemInfo.supports3DTextures) },
                { "SI:SupportsComputeShaders", tag(SystemInfo.supportsComputeShaders) },
                { "SI:SupportsInstancing", tag(SystemInfo.supportsInstancing) },
                { "SI:SupportsSparseTextures", tag(SystemInfo.supportsSparseTextures) },
                { "SI:SupportedRenderTargetCount", tag(SystemInfo.supportedRenderTargetCount) },
                { "SI:SupportsStencil", tag(SystemInfo.supportsStencil) },
                { "SI:NPOTsupport", tag(SystemInfo.npotSupport) },
                { "SI:DeviceName", tag(SystemInfo.deviceName) },
                { "SI:DeviceModel", tag(SystemInfo.deviceModel) },
                { "SI:SupportsAccelerometer", tag(SystemInfo.supportsAccelerometer) },
                { "SI:SupportsGyroscope", tag(SystemInfo.supportsGyroscope) },
                { "SI:SupportsLocationService", tag(SystemInfo.supportsLocationService) },
                { "SI:SupportsVibration", tag(SystemInfo.supportsVibration) },
                { "SI:DeviceType", tag(SystemInfo.deviceType) },
                { "SI:MaxTextureSize", tag(SystemInfo.maxTextureSize) },
            };

            addExtraData.addTags((name, value) => tags[name] = tag(value));

            // Extra contextual data is limited to 4096 characters.
            var extras = new Dictionary <string, object> {
                { "App:StreamedBytes", Application.streamedBytes },
            };

            addExtraData.addExtras((name, value) => extras[name] = value);

            var json = new Dictionary <string, object> {
                { "event_id", Guid.NewGuid().ToString("N") },
                // max length - 1000 chars
                { "message", data.message.trimTo(1000) },
                { "timestamp", timestamp.ToString("yyyy-MM-ddTHH:mm:ss") },
                { "level", logTypeToSentryLevel(data.errorType) },
                { "logger", loggerName },
                { "platform", Application.platform.ToString() },
                { "release", appInfo.bundleVersion },
                { "tags", tags },
                { "extra", extras },
                { "stacktrace", new Dictionary <string, object> {
                      { "frames", stacktraceFrames }
                  } }
            };

            if (!data.backtrace.isEmpty())
            {
                json.Add("culprit", data.backtrace[0].method);
            }

            var serialized = Formats.MiniJSON.Json.Serialize(json);

            return(new SentryMessage(keys, timestamp, serialized));
        }
Ejemplo n.º 9
0
 public static ErrorReporter.OnError createOnError(
     string reportingUrl, string apiKey, ErrorReporter.AppInfo appInfo
     )
 {
     return(data => xml(apiKey, appInfo, data).send(reportingUrl));
 }