社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
日志在开发过程中的作用自不必说,一旦程序出现问题,我们首先想到的是通过日志监控去追查。
好的日志可以通过应用程序执行的历史记录模拟出用户在使用程序的时候操作的完整过程。
为了便于我们分析程序哪里出现问题,我们将采用logrock
模块并将其链接到ElasticSearch,LogStash和Kibana进行进一步分析。
logrock模块源于研究Cleverbrush时候的创新。它是一个用于处理矢量图形的软件。使用图形编辑器意味着大量的应用程序用例。为了控制成本,不得不优化整个开发测试流程。减少每个环节使用测试用例带来的额外的付出。
该模块可以为您的应用程序组织现代化的日志记录方法。 根据日志,我们测试了我们的应用程序。 在本文中,我将向您介绍如何组织日志系统以搜索错误。
一旦程序出现错误(或者用于特殊模拟),则应用程序会将日志发送到服务器,然后将日志保存到文件中。Logstash将数据增量保存到ElasticSearch数据库。用户登录到Kibana并查看保存的日志。
以上就是一个配置好的Kibana的界面,显示了来自ElasticSearch的数据。它可以帮助您分析数据并从中了解程序发生了什么故障。
这里就不一一将如何去设置ElasticStack。
这里我们将一个日志记录系统集成到基于React开发的单页应用程序中。
npm install logrock --save
import { LoggerContainer } from "logrock";
<LoggerContainer>
<App />
</LoggerContainer>
LoggerContainer
是一个捕捉应用程序中的错误并将它们形成堆栈的组件。
堆栈是一个对象,其中包含有关用户的操作系统,浏览器,按下的鼠标或键盘按钮的信息,当然还有操作相关的子数组,其中记录了用户在系统中执行的所有的操作。
LoggerContainer
含有配置项,可适当考虑更改其中的一些设置。
<LoggerContainer
active={true|false}
limit={20}
onError={stack => {
sendToServer(stack);
}}
>
<App />
</LoggerContainer>
为了生产高质量的用户操作日志,我们将日志代码覆盖到所有需要打印日志的地方
logrock
模块附带一个与 LoggerContainer
连接的记录器。
例如,我们有以下这样一个组件:
import React, { useState } from "react";
export default function Toggle(props) {
const [toggleState, setToggleState] = useState("off");
function toggle() {
setToggleState(toggleState === "off" ? "on" : "off");
}
return <div className={`switch ${toggleState}`} onClick={toggle} />;
}
为了能让日志正确覆盖到,我们需要修改toggle方法:
import React, { useState } from "react";
import logger from "logrock";
export default function Toggle(props) {
const [toggleState, setToggleState] = useState("off");
function toggle() {
let state = toggleState === "off" ? "on" : "off";
logger.info(`React.Toggle|Toggle component changed state ${state}`);
setToggleState(state);
}
return <div className={`switch ${toggleState}`} onClick={toggle} />;
}
我们添加了一个logger方法,其中的信息分为两部分。‘React.Toggle’用于显示该动作发生在React的Toggle组件级别。后面是对该动作和发生所在组件的一些描述信息。日志级别划分不是必须的,但是这样有助于我们快速定位错误发生的有关代码。
我们还可以使用 React 16 中引入的“componentDidCatch”方法来捕获异常。
假设我们有一个从后端收集用户数据的方法。该方法是异步的,部分逻辑隐藏在后端中。看看如何将日志添加到代码中?
首先,由于我们有一个客户端应用程序,所有发送到服务器的请求都将在一个用户会话内传递,而无需重新加载页面。 为了将客户端上的操作与服务器上的操作相关联,我们必须创建一个全局SessionID并将其添加到针对服务器的每个请求头的标记中。 在服务器上,我们可以使用任何记录器来记录我们的逻辑,如前端示例所示,如果发生错误,请将带有附加sessionID的数据发送到ElasticSearch,发送到后端。
window.SESSION_ID = `sessionid-${Math.random().toString(36).substr(3, 9)}`;
我们需要将SessionID
添加到请求头中。如果我们使用以及封装好的请求库,很容易将声明好的SessionID添加到所有的请求中。
let fetch = axios.create({...});
fetch.defaults.headers.common.sessionId = window.SESSION_ID;
LoggerContainer
有专门的sessionID字段
<LoggerContainer
active={true | false}
sessionID={window.SESSION_ID}
limit={20}
onError={stack => {
sendToServer(stack);
}}
>
<App />
</LoggerContainer>
前端请求类似下面:
logger.info(`store.getData|User is ready for loading... User ID is ${id}`);
getData('/api/v1/user', { id })
.then(userData => {
logger.info(`store.getData|User have already loaded. User count is ${JSON.stringify(userData)}`);
})
.catch(err => {
logger.error(`store.getData|User loaded fail ${err.message}`);
});
它是怎么运行的呢?
我们在客户端请求之前写一个日志。 从我们的代码中,我们可以看到现在开始从服务器下载数据。 我们已将SessionID附加到请求。 如果我们的后端日志包含此SessionID的添加而请求失败,那么我们可以看到后端发生了什么。
因此,我们不仅在客户端而且还在服务器上监视应用程序的整个周期。
有些日志对用户是有帮助的。向用户输出必要的信息可以采用 stdout
方法
<LoggerContainer
active={true | false}
limit={20}
bsodActive={true}
bsod={BSOD}
onError={stack => {
sendToServer(stack);
}}
stdout={(level, message, important) => {
console[level](message);
if (important) {
alert(message);
}
}}
>
<App />
</LoggerContainer>
我们通过logger传递的第二个参数的值为true来声明这是一个重要的信息,需要通过pop-up窗口显示给用户看,比如在数据加载的时候失败了,我们将输出以下错误信息:
logger.log('Something was wrong', true);
当我们完成编码对外发布应用程序的时候,如果把程序比作一个生命,那么这个生命才刚刚开始。收集并监视日志可以获得产品的反馈帮助更好的改善。
欢迎关注公众号“太空编程”,带你了解硬核的编程知识
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!