background

A log, as a re-enactment, is a useful tool in many situations. Like the black box on an airplane, it’s an integral part of the system. I have personally encountered the following scenarios that require front-end logging.

  1. The background logs are lost due to a network problem between the front end and the back end, and the front end needs to record request logs.
  2. Products need to know part of the function of clicking PV, UV, need to have a log of events

note

  1. The following access instructions list examples of events and requests, some of which can be shared and are not repeated
  2. Requests are XMLHttpRequest only, not Fetch

Trackless access

Modify native methods

In the case of requests, whether they are made using AXIos or jquery. ajax is actually made using the browser’s native XMLHttpRequest. Also, XMLHttpRequest is a method on the Window object, so simply adding logging to this method before the request is sent can log every request

window.XMLHttpRequest.prototype.send = function() {
  // Report
  console.log(arguments);
  return window.XMLHttpRequest.prototype.send.apply(this.arguments);
}
Copy the code

Disadvantages:

  1. Source code modification, can only ensure the use of the original function, secondary source code coverage modification, very prone to error exceptions
  2. As the least intrusive way, but also the most polluting way, all requests are affected. Because the execution parameters of the original method cannot be adjusted, the reported behavior is fixed when the code is written, and it is almost impossible to modify the reported content later.

Bubbling through events

Take events as an example. During click reporting, Dom clicked on the page can be captured through event bubbling.

// You can obtain relevant content of the DOM node clicked through event for reporting
window.addEventListener('click'.(event) = > console.log(event.target.textContent));
Copy the code

disadvantages

  1. If dom nodes are prevented from bubzing (Event.stopPropagation), they will not be captured properly
  2. When a node is deleted, the parentNode cannot be correctly obtained due to the trigger timing (the node is removed from the DOM tree after being clicked by itself first, and the asynchronous trigger event bubbles)

StopPropagation problem can modify stopPropagation native method Resolve the above problems can be unified by modifying Element. The prototype. The addEventListener native method

Unified call access

Using this approach adds a layer to the original invocation chain, requires modifications to the original business introduction method, and requires multifaceted testing and error compatibility to avoid impacting the original execution

The middle tier invokes object modification

The front-end typically does not use XMLHttpRequest directly, but rather requests through AXIOS, so you can inject logging services against the API provided by axiOS objects.

const instance = axios.create();
instance.interceptors.response.use(function (response) {
    // An HTTP success log is reported
    console.log(response);
    return response;
  }, function (error) {
    // HTTP failure log is reported
    return Promise.reject(error);
  });
export default instance;
Copy the code

Pay attention to

  1. If the project does not use a unified AXIOS instance, it can also be modified for the default AXIOS
  2. According to the interceptors source code, the object returned by the return will still be used in the future and should be retained
  3. When the network is replaced by exception interception, the response may not contain the complete content of the request, and it needs to be nulled

The middle tier invokes component modifications

The following example is Vue2.0+ElementUI

export default {
  extends: ElRadio,
  methods: {
    // This method is triggered by default when data is updated in the source code, so log reporting control is implemented for this method
    handleChange() {
      // By default, slot or label is supported to display text
      const label = isEmpty(this.$slots)
        ? this.label
        : this.$slots.default
          .map(({ elm }) = > trim(elm.textContent))
          .join(' ');
      // Logs are reported
      console.log(label);
      // The original method needs to continue
      ElRadio.methods.handleChange.call(this); ,}}};Copy the code

The characteristics of

  1. You use this method because you are inside the component, so you can get context information about the component
  2. After vUE inherits, only the newly declared methods will be executed. Note that the original methods need to be executed to ensure normal data interaction

Active declarative access

This method will not be described in detail, is to actively log the line of code that needs to use the log report. Can be the most customized context information you want, is also the most special dog plaster code (has nothing to do with the actual logic)

conclusion

The specific log access mode depends on the service situation. I recommend using the access mode of the middle layer for control. If you want to remove logs, you can modify them uniformly in the middle layer, or add ignore to the middle layer for dynamic control.