Author: Yao Zeyuan

Section profile

This week’s worth of tech content, released on Thursday

Determine the file type

Mime-types, which can quickly infer file mime-types from file names. When uploading a CDN file, you often need to provide the content-type of the file to confirm the cache scheme, for example: ‘application/json’/’text/markdown’/’ image/ BMP ‘. Mime-types can solve this problem.

TS spooky error reported

While compiling code using TSC, an unexpected TypeError: Class Constructor Command cannot be invoked without ‘new’ was reported.

Google later discovered that the reason was that the compiled target was written as ES5.

In [ES6 manual -class][es6.ruanyifeng.com/?search=con…], the constructor method can only be called by new, otherwise an error will be reported.

However, ES5 does not have this rule, and TSC uses the Apply/Call method to simulate new Class calls, resulting in errors. The fix is as simple as changing the target in tsconfig.json to ES6.

Details as follows:

The original code = >

ES5 conversion error (emulates class instantiation) =>

ES6 Normal after conversion =>

Best logging Practices

This week, I was responsible for the log implementation of the monitoring system. Collected several good log practice summary on the network at present. Summary as follows

  1. Logs are classified into diagnostic logs, statistics logs, and audit logs

Diagnostic logs, typically:

Request entry and exit External service invocation and return Resource consumption operations: fault-tolerant behaviors such as reading and writing files: for example, a copy of a cloud hard disk Repair operation program exception: For example, a database fails to connect to the background operation: periodically start and close deleted threads, and load configurations

Statistical log:

User access statistics: accounting logs such as user IP addresses, data volume uploaded and downloaded, and request time (for example, network resources and disk usage are recorded in strict format for easy statistics)

Audit log:

Management Operations For a simple system, all logs can be output to the same log file and distinguished by different keywords. For a complex system, it is necessary to output logs with different requirements to different log files. You can use different log formats for different types of files (for example, you can output charging logs in Json format) to facilitate access to other subsystems.

  1. The ideal log should contain no more, no less information.

By not much, I mean don’t record useless information in the log. A lot means that users of logs can get all the information they need from logs

  1. Note that the following data items are usually missed in logs

System configuration parameters

Tasks that are periodically executed in the background

Exception handling logic

Logs record key parameters and key causes of errors

  1. Log monitoring
  1. If the alarm can be avoided, the alarm will not be sent. Only the errors that need to be handled by O&M immediately need to be reported. The reason for doing this is to avoid long-term alarm harassment so that operation and maintenance personnel are no longer sensitive to the alarm. When the alarm finally comes, it becomes a legend that the Wolf is crying.
  2. Specify alarm keywords, such as ERROR, rather than a variety of complex rules. The reason for this is that the nature of log monitoring is continuous string matching. If there are too many and too complex rules, online services may be affected.
  3. For some early warning operations, such as a service that needs multiple retries to succeed, or a user whose quota is about to be used up, you can send an alarm email every day. Every time the system fails, it is necessary to timely check whether the log alarm is sensitive, whether the description of the log alarm is accurate, and constantly optimize the log alarm;

This is from @WangJian’s Best Logging Practices (V2.0)

But in practice, we know. The output log looks like this (from log4j):

19:08:07.062 TRACE com.test.TestService 27 exampleException – Entry 19:08:07.077 DEBUG com.test.TestService 32 exampleException – catching java.lang.ArrayIndexOutOfBoundsException: 3 at com.test.TestService.exampleException(TestService.java:29) [classes/:?] at com.test.App.main(App.java:9) [classes/:?] at com.test.AppTest.testApp(AppTest.java:15) [test-classes/:?] At sun. Reflect. NativeMethodAccessorImpl. Invoke0 (Native Method) ~ [? : 1.6.0 _29] the at Sun. Reflect. NativeMethodAccessorImpl. Invoke (NativeMethodAccessorImpl. Java: 39) > ~ [? : 1.6.0 _29] the at Sun. Reflect. DelegatingMethodAccessorImpl. Invoke (DelegatingMethodAccessorImpl. Java: 25) ~ [? : 1.6.0 _29] the at Java. Lang. Reflect. Method. Invoke (597) Method. The Java: ~ [? : 1.6.0 _29] the at Org. Junit. Internal. Runners. TestMethodRunner. ExecuteMethodBody (99) TestMethodRunner. Java: / junit – this jar:?

Therefore, in the final formulation of the log scheme, we choose to separate the monitoring log and the running log.

Service logs use a common format. Type specifications are formulated for monitoring logs based on different types. TS is used to define log types. Specific use, according to the type + version field can uniquely determine the data type structure, using the TYPE declaration function of TS can achieve code prompts for analysis

The sample is as follows

Reference log4j2 / * * * * / type LogLevel = "debug" | "info" | "warn" | "error". / log categories according to the Type decision * * * * / Type LogType = | "server_start" | "server_runtime" | "common_log"; Interface BaseLoggerType {/ * * * specific types of log. * / type: LogType | String; /** * marks the log version. When the data structure changes, we can change the version to distinguish data records * refer to the HTTP protocol, because the dot structure is basically unchanged, so only two bits of the version number is needed */ version: "0.1"; / * * * logging time, millisecond * / timestamp_ms: 1566788860106 | number; /** * Project_code: String; Dot / * * * current * / env environment: 'dev' | 'st' | 'prod' dot / * * * whether to ignore the record, to speed up the resolution, using keywords said need to ignore some record, matching to the keyword that ignore the rbi log * / is_ignore: '|' 61013998 c3dd0ca3bb6b8fd1c325086b / * * * details data, different categories of data * / detail: {/ / strong constraint key = > value keys for each log / / category bans on key values. Through the type + version field only certain data types (key: string) : string | Number | Object; }; /** * extension field */ extra: {// Any key=>value passed by the business side/SDK is for record only. Don't parse [key: string] : string | Number | Object; }; } interface ServerStartInfoLog extends BaseLoggerType {/** * When a server is started, record information */ type: "server_start"; Detail: {/** * Number of cpus. If the number is greater than 1, the number is multi-core */ cpu_count: number. / * * * service process startup time (millisecond timestamp) * / start_at_ms: 1566788860106 | number; }; }Copy the code