background

Although there will be a lot of testing procedures before our project goes online, the testing procedures certainly cannot guarantee 100% coverage of all operating scenarios, and there will still be some problems exposed in the use of users. However, when problems arise from online users, we need to receive feedback from users before we can locate and solve them, which will lead to our problems not being solved in a timely manner. And some difficult and complicated diseases, we can not reproduce the location, at this time we need to know the user’s environment, operation and other information, in order to facilitate the troubleshooting of the problem. Based on the above three considerations, I think it is necessary to access an exception monitoring system in most projects to collect exceptions, log information, timely warning, display statistics and other functions.

Why Sentry?

  • free
  • Sentry can be used directly or built in-house
  • Strong compatibility, basic language restrictions, build a set of systems can be used for multiple projects.

Sentry profile

Sentry’s application monitoring platform helps every developer diagnose, fix, and optimize the performance of their code.

Sentry’s application monitoring platform helps every developer diagnose, fix, and optimize the performance of their code.

Sentry deployment and use

Sentry can be used directly or built on your own. The following section explains how to build a Sentry. Those who want to experience it directly can skip it and go directly to the official website.

The official installation method is to use Docker and Docker Compose and base-based installation and upgrade scripts.

Environmental requirements

  • The Docker 19.03.6 +
  • Compose 1.24.1 +
  • 4 CPU Cores
  • 8 GB RAM
  • 20 GB Free Disk Space
  • Python 3

Here is not the configuration of the environment in detail, want to build their own students can refer to the following article.

  • Install and upgrade docker using yum
  • Python3 is installed on CentOS 7

Deployment steps

  1. Get the latest Sentry code from Github.
git clone https://github.com/getsentry/onpremise.git
Copy the code
  1. Go to onpremise and run the install.sh script.
cd onpremise
./install.sh
Copy the code
  1. rundocker-compose up -dTo start Sentry.

By default, Sentry is bound to port 9000. You can access the login page by visiting http://127.0.0.1:9000.

  1. Open the page and enter the information to enter the Sentry system

  1. Configure the automatic sending of warning emails, either from the above figure or from the configuration file, as shown in the following configuration tutorial via config.yml.

Open the config.yml file in onpremise/ Sentry to modify the Mail Server configuration.

  • Mail. backend: mail sending mode.
  • Mail. host: SMTP sending domain name, which mailbox can be found in the mailbox document.
  • Mail. port: indicates the port number for sending mails.
  • Mail. username: indicates the SMTP mailbox account.
  • Mail. password: password used for SMTP email.
  • Mail. use-tls: indicates whether to use the TLS security protocol. Set this parameter to true or false.
  • Mail. use-ssl: specifies whether to use the SSL protocol. Set this parameter to true or false.
  • Mail. from: indicates the name of the sender when the mail is received.
  1. Run this command after modifying the mail service through the configuration filedocker-compose up -dUpdate the Sentry. If the update fails, you need to shut down docker-compose and re-run it.
docker-compose down
docker-compose build
docker-compose up -d
Copy the code

After the restart, you can enter the mail configuration page through profile picture -> admin -> mail and click Send test mail to check whether the configuration is successful.

Sentry sets access over HTTPS

Now we need to configure SSL for the Sentry so that we can use HTTPS.

First to modify onpremise sentry/config. Yml system. – the prefix url configuration, it is set for us to visit the sentry of the domain name. Url-prefix forms the DSN address of the project, and must be formatted correctly.

system.url-prefix: 'https://sentry.xxxxx.com:60000'
Copy the code

Then the onpremise sentry/sentry. Conf. Py files under the SSL/TLS configuration, parts of the original annotation is opened entirely.Docker-compose should also be closed and rebuilt after modification.

docker-compose down
docker-compose build
docker-compose up -d
Copy the code

Sentry allows the SSL proxy to pass through the Sentry server. We need to set up an Nginx server to forward HTTPS content. Here is my nginx configuration. Once you have configured nginx and restarted it, you are done. Our Sentry is finally accessible via HTTPS!

server {
    Configure the listening port
    listen       60000 ssl http2 default_server;
    listen[: :] :60000 ssl http2 default_server;

    # the domain name
    server_name  sentry.xxxxx.cn;

    # nginx default root directory
    root         /usr/share/nginx/html;

    Load other configuration files. This is the default configuration of nginx
    include /etc/nginx/default.d/*.conf;

    # SSL Settings
    ssl on;
    # SSL certificate address
    ssl_certificate     /etc/nginx/sslcert/server.crt;
    # SSL key address
    ssl_certificate_key /etc/nginx/sslcert/server.key;
    ssl_session_cache shared:SSL:1m;
    ssl_session_timeout  10m;

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphersEECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:! MD5;ssl_prefer_server_ciphers on;


    client_max_body_size 200M;
    client_body_buffer_size 1024k;

    # this paragraph is the most important, the domain name proxy to the local http://localhost:9000 service, corresponding to the docker sentry service
    location / {
        proxy_pass http://localhost:9000;
    }

    gzip  on;
    gzip_http_version 1.1;
    gzip_vary on;
    gzip_comp_level 9;
    gzip_proxied any;
    gzip_types text/plain  text/css application/json  application/x-javascript text/xml application/xml application/xml+rss text/javascript application/x-shockwave-flash image/png image/x-icon image/gif image/jpeg;
    gzip_buffers 16 8k;

    error_page 404 /404.html;
        location = /404.html {
    }

    error_page 500 502 503 504 /50x.html;
        location = /50x.html {
    }
}
Copy the code

Sentry Access instance

The Sentry system is set up by the procedure above, and access the configured address to enter the Sentry system. Friends who do not have the construction can also experience the process of accessing the project directly through the official website.

Create a project

Click New Project in the upper right corner of the system to create a Project.

The React project is used as an example to establish a React project. You can register Sentry in the project according to the prompts on the page to catch exceptions during project execution.

configuration

Sentry configuration should occur early in the application lifecycle. Once this is done, Sentry’s JavaScript SDK catches all unhandled exceptions and transactions. Init parameter description:

Sentry.init({
  // DSN of Sentry project, available from project Settings
  dsn: "https://[email protected]:9000/2".// Initial parameter configuration
  integrations: [new Integrations.BrowserTracing()],
  // The probability of sending an exception to Sentry
  tracesSampleRate: 1.0.// Controls the amount of crumbs (behavior stack) that should be captured
  maxBreadcrumbs: 20.// Specifies the depth of the context data structure, which defaults to 3
  normalizeDepth: 100.// Version information
  release: "[email protected]".// Environment information
  environment: process.env.NODE_ENV,
  // The hook function that fires every time an event is sent
  beforeSend(event) {
    // The variable will disappear after the web app is refreshed, so I choose to insert the user information when beforeSend is triggered
    event.user = {
      userNick: "xiaohu"};returnevent; }});Copy the code

Set a variable

In Sentry, you can set variables using the form set tags, extra, contexts, user, level, fingerprint. Here are a few ways to do this. For details, see the documentation.

Example of setting global variables using setUser User information (not recommended)

To catch exceptions, user information also needs to be collected. After the user logs in, setUser needs to set the global variable of user information, as shown below. ** Note that global variables set in this way disappear when the page is refreshed. ** Set user information code:

Sentry.setUser({
    tenant: {
        code: 12345.name: 'Test Company'._id: 12345
    },
    orgAccount: {
        _id: 54321.orgName: 'It's an institution.'
    },
    user: {
        _id: '8910JQ'.loginName: 'Q tester'}})Copy the code

The user data uploaded can be seen in the issue triggered after setting the global variable.

Insert user information through beforeSnd

Global variables set by Sentry mechanism will disappear after page refresh. I recommend using beforeSend function to modify the data in event to insert the required global variables.

Sentry.init({ ... .// The hook function that fires every time an event is sent
    beforeSend(event) {
        // Here you can send user information according to the business situation
        event.user = {
            userNick: 'xiaohu'
        };
        returnevent; }});Copy the code

Setting global variables

// The following are global variables defined by Sentry, which can be set directly using the Sentry API
Sentry.setUser(object);
Sentry.tags(object);
Sentry.extra(object);
Sentry.level(object);
Sentry.fingerprint(object);

// Use setContext to set the key value, which can be customized with the variable name passed with the event
Sentry.setContext(key, context);
Copy the code

Setting local variables

CaptureException sentry. captureException(err[, obj]) the first parameter is the exception thrown, and the second parameter can attach an error message. The second parameter is an object. The key value can be tags, Extra, context, user, level, or fingerprint.

Sentry.captureException(error, {
  contexts: {
    message: {
      a: 1.b: { b: 1}},}});Copy the code

Example of setting local variables Network error message

According to axiOS, which is currently used in the front-end framework, local data of network request errors are collected. Code example:

Sentry.captureException(error, {
  contexts: {
    message: {
      url: error.response.config.baseURL + error.response.config.url,
      data: error.response.config.data,
      method: error.response.config.method,
      status: error.response.status,
      statusText: error.response.statusText,
      responseData: JSON.stringify(error.response.data),
    },
  },
});
Copy the code

Clear global variables

After a user logs out, you can clear the user information in the following two ways.

  1. By setting it to null, you can clear the data that has been set.
Sentry.setUser();
Copy the code
  1. throughscope.clear()Clear global variables.
Sentry.configureScope((scope) = > scope.clear()); // Clear all global variables
Sentry.configureScope((scope) = > scope.setUser(null)); // Clear the user variable
Copy the code

Uploading Log Information

The sentry. captureMessage(Err [, obj]) API is used to send logs to the page. Use the same method as captureException. It is recommended to set level to Info to distinguish it from exceptions and avoid triggering the exception alert we set.

Sentry.captureMessage("Something went fundamentally wrong", {
  contexts: {
    text: {
      hahah: 22,}},level: Sentry.Severity.Info,
});
Copy the code

Upload sourceMap

Sentry can upload the SourceMap of the front-end project packaged so that we can see the code location of the exception. Sentry integration sourcemap

Uninstall the sentry

For uninstallation, please refer to the following link. How do I uninstall Sentry?

Raise an exception and see

onClick={() = > {
	let a = {};
	console.log(a.b.c);
}}
Copy the code

Here I create an exception code, and when clicked you can expect a JS error to appear, as shown below.

In network we can see a request, Sentry upload error in this way.

When you go to the Sentry system page, you can see a message in the Issues panel:

Click in to see more information about this exception.

It can be seen that a large amount of data related to exceptions has been collected in details, such as device, browser version, IP address, error data, user operation stack and other data. However, this data alone is not enough, and the original uploaded information is sometimes not enough to analyze the problem. In many cases, we need to customize the collected data according to the business scenario. Next, we will analyze the scene capture and content collection.

Exception information capture scenario and collection content

Capture the scenario

For common front-end service scenarios, service error information needs to be collected in the following scenarios.

  1. Interface error
  2. Network error
  3. Js error an error
  4. Major service processes are abnormal
  5. Internal iframe/ webView error

Reject: new error or Promise.reject(error) : new error or Promise.reject(error) : new error or Promise.reject(error) : Can be collected by Sentry. Or use the captureMessage Api to collect run logs.

Collection content

Although the Sentry SDK will catch all unhandled exceptions and transactions and report them to the system, it will also record the page and device information that generated the exception. But this information is not enough, and additional business information is needed to better identify problems. Here’s my summary of what I need to collect to report an exception.

Exception message: The Sentry automatically captures the error message when an exception is thrown.

User information: user information (such as login name, ID, and level), organization information, and company information.

Behavior information: The user’s operation process, for example, after logging in to xx page, click XX button, Sentry will automatically capture.

Version information: The version information (test, production, grayscale) of the running project, and the version number.

Device information: The platform used by the project. Web projects include running device information and browser version information. Mini program items include the phone model, system version and wechat version of the running phone.

Timestamp: Records the time when an exception occurred, and Sentry automatically captures it.

Exception level: According to the Sentry document, there are several levels.

  • Critical
  • Debug
  • Error
  • Fatal
  • Info
  • Log
  • Warning

Platform information: Record the item where the exception occurs.

With the above content of the completion, plus the original exception data, for an error is not more clear.

Applets access Sentry

Sentry has no official API to provide for small programs. Fortunately, a third party can use the original API to implement exception monitoring on the small program side based on the library provided.

The installation

  • npm install sentry-mina –save
  • yarn add sentry-mina
  • Copy browser/sentry-mina.js into the project

use

import * as Sentry from "sentry-mina/browser/sentry-mina.js";
// import * as Sentry from "sentry-mina";
// config Sentry
Sentry.init({
  dsn: ""});// Set user information, as well as tags and further extras
Sentry.configureScope((scope) = > {
  scope.setUser({ id: "4711" });
  scope.setTag("user_mode"."admin");
  scope.setExtra("battery".0.7);
  // scope.clear();
});
// Add a breadcrumb for future events
Sentry.addBreadcrumb({
  message: "My Breadcrumb".// ...
});
// Capture exceptions, messages or manual events
Sentry.captureMessage("Hello, world!");
Sentry.captureException(new Error("Good bye"));
Sentry.captureEvent({
  message: "Manual".stacktrace: [
    // ...]});Copy the code

See the documentation for the Sentry Applets SDK for additional details.

The problem summary

Here are some of the problems I had with the Sentry and its subsequent use.

The Consolelog does not display the Sourmap address

The reason for this problem is that Sentry changes the native Console method to collect the console, so the Sourcemap address is not displayed here, and you can unregister Sentry in a development environment.


This post was first posted on my blog mogii’blog