【老板要你啥都会系列】| 前端晋升全栈--项目日志

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 日志包含什么访问人数啊、峰值啊、 bug 啊什么的,如果没有日志那么很容易失控。 访问日志可以参考我们 http-server ,每次访问都会有这些东西。

1.开篇

  日志包含什么访问人数啊、峰值啊、bug 啊什么的,如果没有日志那么很容易失控。 访问日志可以参考我们 http-server,每次访问都会有这些东西。自定义日志是则并不是每次访问都打印的,根据情况或自己的需要,有点像 console.log。

日志:

  • 系统没有日志,就等于人没有眼睛——抓瞎
  • 第一,访问日志 access log ( server端最重要的日志)
  • 第二,自定义日志(包括自定义事件、错误记录等)

开发的话自然是打印在控制台,而上线了当然是要把日志保存到文件中。 如果不用 stream 的话,直接操作文件会很大的消耗 cpu 和内存。

目录

  • nodejs文件操作,nodejs stream
  • 日志功能开发和使用
  • 日志文件拆分,日志内容分析

日志文件很大自然不可能放到 redis(占超级多内存而且也是异步的,没必要马上记日志)mysql 的话需要表结构(B树)才比较合适(而且文件每个地方都可以访问,不必要安 装 mysql 文件)。

nodejs文件操作

  1. 日志要存储到文件中
  2. 为何不存储到mysql中?
  3. 为何不存储到redis中?

2.nodejs文件操作

  新建一个文件夹 file-test ,直接建一个 test1.js ,引入两个 node.js 自带的 fs 和 path 库(因为 Linux 和 windows 的文件目录路径是不一样的,需要这个 path 来统一)。 再建一个 data.text ,随便写点什么作为我们测试的文件。 回到 test1 ,利用 resolve 方法, __dirname 代表当前文件的目录获取到 data 我们就去读取文件, readFile 方法,异步的 (注意获取的是数据其实是二进制,记得转换成字符串)。

 但是按照目前这种写法,虽然可以打印出 data ,倘若这个 data 有 5 个 G 这么大,我们还这样搞,那么势必是比较浪费性能和内存(一个进程最大也就 3G )的。

  先看怎么写入文件,定义写入的文件,定义 option(flag 为 a 代表 append 追加写入,而 w 是直接覆盖)。然后就可以调用 writeFile(包含四个参数:要被写入的文件、写入的内容、 选项、回调函数)。同理,写入也是有耗费性能的情况(每次写入一行都 writeFile,一直 writeFile,就不停的打开文件,而且也很难写入非常大的数据)。再看看另一个,判断文件是否存在,调用 exists 方法,接收文件名和回调,会返回一个布尔值,注意也是异步。

const fs = require('fs' ) 
const path = require( 'path')
const fileName = path.resolve(_dirname, 'data.txt') //拿到要操作的文件
//读取文件
fs.readFile(fileName,(err ,data) => {
  if (err) {
    console. log(err)
    return 
}
    console. log(data.tostring()) //注意拿到的是二进制文件,需要转换成字符串!
})
//写入文件
const content ='三星阿卡丽\n'   //随便写入点东西
const opt =
   flag:'a'
} //定义写入的形式,a代表追加写入
fs .writeFile(fileName, content, opt, (err) => {
   if (err) {
       console.log(err) 
      return
}
})

3.stream

   IO 就是输入输出(input 和 output)。网络 IO 常见于视频播放几个 G,不可能直接下载到客户端再看,一来占用内存,二来带宽问题。IO 实在是慢,读写文件发送网络请求什么的。

IO操作的性能瓶颈:

  1. IO包括"网络IO”和"文件IO"
  2. 相比于CPU计算和内存读写, IO的突出特点就是:慢!
  3. 如何在有限的硬件资源下提高I0的操作效率?

借助下图来说,我们之前操作文件就是直接把整个桶给搬起来到到另一个桶,这就要你力气大(硬件资源超好,带宽超强)。但是在资源有限的情况下,那个管子插进去慢慢流就好,慢慢加载。

2345_image_file_copy_502.jpg

stream

实际上 request response 都是继承了 stream 的一些特性或者说本身就是 stream

4.stream演示

新建一个 stream-test 文件夹,新建一个 test1.js 。其实这个 pipe 就是 Linux 里面的标准输入出,输入啥打印啥,不用管,std 就是标准的意思, in 就是输入嘛, out 就是输出咯。就演示一下管道,输入就是流入嘛,输出就是流出嘛。接下来演示那个直接返回 request 数据,这里我们 post 的 request 内容就是 response 展示的内容, request 和 response 是桶,用管道连接,是流的关系。当然要是输入的很多,就 会一点点的流过去。 接下来是操作文件对象。

var fs = require('fs')
var path = require( 'path')
//两个文件名
var fileName1 = path.resolve(_dirname,
data. txt')
var fileName2 = path.resolve(_dirname, 'data-
bak. txt')
//读取文件的stream 对象
var readStrekm = fs. createReadStream( fi leName1)
//写入文件的stream 对象
var writeStream = fs.createWr iteSt ream(f i LeName2 )
//执行拷贝,通过pipe
readSt ream. pipe (writeSt ream )
//数据读取完成,即拷贝完成
readStream. on( 'end', function () {
console. log('拷贝完成')
})

创建写入文件和读取文件两个对象(桶)读取文件的话是从 stream 传给返回值,这些都是变成桶与桶然后流转过去,效率非常高。

//直接返Erequest数据
const http = require( http' )
const server = http .createserver((req, res) => {
    if (req.method === 'POST') {
   req.pipe(res) //从我们发送的request波到传回来的response,显示在返回结果那里
}
})
server.listen(8008)

创建两个随便的数据文件 data.txt data-bak.txt ,导入这两 个文件,分别创建读与写两个 stream 对象(桶)。这个同样可以监听 data end(这样子就知道确实是一点点读取文件的,而传统的操作是一下子都给拿出来)

//复制文件
const fs = require('fs' )
const path = require('path')
const fileName1 = path.resolve(_ dirname, 'data.txt' )
const fileName2 = path. resolve(_ dirname, 'data-bak.txt')
const readstream = fs .createReadstream(fileName1)
const writestream = fs.createwritestream(fileName2) //拿到对应的文件且创建读写对象
readstream.pipe(writestream) //将读到的文件流入写入的文件(也就是拷贝了)
readstream.on('data', chunk => { 
    console. log(chunk.tostring())
})
readstream.on('end', () => { //监听拷贝完成
console.log('copy done ' )
})
// http请求 文件
const fs = require('fs' )
const path = require('path')
const http = require('http')
const fileName1 = path.resolve(_dirname,'data.txt')
const readstream = fs .createReadstream(fileName1 )
const server = http.createserver((req, res) => {
   if (req.method === 'GET') {
        readstream.pipe(res) //直接将读取到的文件一点点传到返回值那里
}
})
server.listen(8000 )

5.写日志

  在 blog-1 下建一个 logs 文件夹,下面建三个文件:access.log、 event.log、 error.log 。 在 src 下建一个 utils 文件夹,里面建一个 log.js 。定义一个 createWriteStream 函数,就是生成右边的桶被写入),由 于只是传入 xxx.log ,所以还需要再拼接一下路径,在当前目 录(utils)上翻一层再上翻一层(blog-1),找到下面的 logs 文件夹,再找到传入的文件,就能拿到真正的地址, 根据这个地址去创建流对象(追加方式)然后返回整个对象即可。

 

   将 access.log 传入建一个对应的流对象,然后再定义一个要传给外面的函数 access (传入 log 参数)用来写访问日志, 写日志我们统一定义成一个函数 writeLog ,接收流对象和 log,直接调对象的 write 方法,传入需要写的内容即可记得换行),在 access 调用这个方法即可,其它的日我

们就不管了,也是一样的道理。 那 么 怎 么 去 用 呢 ? 回 到 aoo.js 获 取 access 方 法 , 在serverHandle 使用,把 method 、 url 、 user-agent 、当前时间 戳传入。由于是通过流写入的,效率很高,每次访问都可以写入东西。

2345_image_file_copy_503.jpg

6.拆分日志

  • 日志内容会慢慢积累,放在一个文件中不好处理
  • 按时间划分日志文件,如2019-02-10.access.log
  • 实现方式: linux的crontab命令,即定时任务

这个由于服务器基本都是 Linux 和类 Linux 的,定时任务的话 windows 可能没办法实现,所以这一块可以了解下即可,主 要是运维的搞。 解释一下*代表什么意思,第一个*代表分钟(如果不写具体 的值保持*就代表忽略,比如 1 * * * *就代表每天的第一分钟执行这个命令)第二个*代表小时(12***代表每天的第二个小时的第 1 分钟执行)第三个是日期第四个是月份第五个是 星期。command 就是一个 shell 脚本。

crontab:

  • 设置定时任务,格式: **** * command
  • 将access.log拷贝并重命名为2019-02-10.access.log
  • 清空access.log文件,继续积累日志

这个完全不需要修改代码,所以肯定是运维来搞,不过了解也是可以的。Node.js 当然也能做这个,但是就比操作系统隔了一层,不如直接通过操作系统的 shell 脚本来操作更加便捷 和高效(也好分离代码)。 回到 utils ,建一个 copy.sh (即 shell 脚本),第一行是固定的即 shell 的执行文件,将 logs 的路径拷贝过去, cd 到 logs , 拷贝 access.log 重命名为当前时间的 access.log 。 echo 移动空字符串到 access.log 相当于清空 access.log 。然后在 Linux 下面执行就行了!

7.分析日志介绍

接下来就是使用 crontab 了,因为前面已经编写好了 shell 脚本,通过输入 crontab -e 进入编辑器,设置时间,执行脚本的时候需要将整个脚本的路径拷贝过去才行。

日志分析:

  1. 如针对access.log日志,分析chrome的占比
  2. 日志是按行存储的, - -行就是一条日志
  3. 使用nodejs的readline ( 基于stream , 效率高)

通过 readline 可以一行行的去查看日志,我们先去不同浏览器运行下不同的地址,创造出不一样的 logs。


8.readline

获取到不同浏览器的日志后,我们回到 utils 下面建一个readline.js,引入 fs 、 path 、 readline 。拿到 access.log ,并且 基于这个建一个 readStream (因为是读操作)。再调用 createInterface 创一个 readline 对象,输入就是流对象。 定义一个储存 chrome 数量的变量和储存总数的变量, on 监 听 line ,每读完一行就会触发。通过 -- 切割数据,第 3 个即数组[2] 就是有关浏览器信息的,看看否包含 Chrome 决定加减。

const fs = require( ' fs' )
const path = require( 'path' ) 
const readline = require('readline')
//创建流对象(读取)
const fileName = path. join(__ dirname, '../', ' ../', 'logs' , access.log' )
const readstream = fs.createReadstream( fileName)
//创建readLine对象
const rl = readline.Interface({
   input: readstream 
})
//定义存放浏览器类型的变量
let chromeNum = 0
letsum=e


相关实践学习
【涂鸦即艺术】基于云应用开发平台CAP部署AI实时生图绘板
【涂鸦即艺术】基于云应用开发平台CAP部署AI实时生图绘板
相关文章
|
8月前
|
Java 微服务 Spring
微服务——SpringBoot使用归纳——Spring Boot使用slf4j进行日志记录——使用Logger在项目中打印日志
本文介绍了如何在项目中使用Logger打印日志。通过SLF4J和Logback,可设置不同日志级别(如DEBUG、INFO、WARN、ERROR)并支持占位符输出动态信息。示例代码展示了日志在控制器中的应用,说明了日志配置对问题排查的重要性。附课程源码下载链接供实践参考。
940 0
|
8月前
|
JSON 自然语言处理 前端开发
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
407 72
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
|
6月前
|
Java 应用服务中间件 Linux
Tomcat运行日志字符错乱/项目启动时控制台日志乱码问题
总结: 通过以上几种方法,概括如下:指定编码格式、设置JVM的文件编码、修改控制台输出编码、修正JSP页面编码和设置过滤器。遵循这些步骤,你可以依次排查和解决Tomcat运行日志字符错乱及项目启动时控制台日志乱码问题。希望这些建议能对你的问题提供有效的解决方案。
1177 16
|
10月前
|
Dart 前端开发
【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
349 75
【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
|
9月前
|
前端开发 Java Shell
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
584 20
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
9月前
|
安全 前端开发 开发工具
【01】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-项目开发实战-优雅草卓伊凡拟开发一个一站式家政服务平台-前期筹备-暂定取名斑马家政软件系统-本项目前端开源-服务端采用优雅草蜻蜓Z系统-搭配ruoyi框架admin后台-全过程实战项目分享-从零开发到上线
【01】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-项目开发实战-优雅草卓伊凡拟开发一个一站式家政服务平台-前期筹备-暂定取名斑马家政软件系统-本项目前端开源-服务端采用优雅草蜻蜓Z系统-搭配ruoyi框架admin后台-全过程实战项目分享-从零开发到上线
456 5
【01】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-项目开发实战-优雅草卓伊凡拟开发一个一站式家政服务平台-前期筹备-暂定取名斑马家政软件系统-本项目前端开源-服务端采用优雅草蜻蜓Z系统-搭配ruoyi框架admin后台-全过程实战项目分享-从零开发到上线
|
9月前
|
JSON 前端开发 API
以项目登录接口为例-大前端之开发postman请求接口带token的请求测试-前端开发必学之一-如果要学会联调接口而不是纯写静态前端页面-这个是必学-本文以优雅草蜻蜓Q系统API为实践来演示我们如何带token请求接口-优雅草卓伊凡
以项目登录接口为例-大前端之开发postman请求接口带token的请求测试-前端开发必学之一-如果要学会联调接口而不是纯写静态前端页面-这个是必学-本文以优雅草蜻蜓Q系统API为实践来演示我们如何带token请求接口-优雅草卓伊凡
459 5
以项目登录接口为例-大前端之开发postman请求接口带token的请求测试-前端开发必学之一-如果要学会联调接口而不是纯写静态前端页面-这个是必学-本文以优雅草蜻蜓Q系统API为实践来演示我们如何带token请求接口-优雅草卓伊凡
|
10月前
|
Dart 前端开发 容器
【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
327 18
【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
|
8月前
|
人工智能 JavaScript 前端开发
Vue 性能革命:揭秘前端优化的终极技巧;Vue优化技巧,解决Vue项目卡顿问题
Vue在处理少量数据和有限dom的情况下技术已经非常成熟了,但现在随着AI时代的到来,海量数据场景会越来越多,Vue优化技巧也是必备技能。 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
9月前
|
Dart 前端开发 Android开发
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
259 4
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex

热门文章

最新文章

  • 1
    前端如何存储数据:Cookie、LocalStorage 与 SessionStorage 全面解析
    344
  • 2
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(九):强势分析Animation动画各类参数;从播放时间、播放方式、播放次数、播放方向、播放状态等多个方面,完全了解CSS3 Animation
    105
  • 3
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(八):学习transition过渡属性;本文学习property模拟、duration过渡时间指定、delay时间延迟 等多个参数
    135
  • 4
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(七):学习ransform属性;本文学习 rotate旋转、scale缩放、skew扭曲、tanslate移动、matrix矩阵 多个参数
    110
  • 5
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(六):全方面分析css的Flex布局,从纵、横两个坐标开始进行居中、两端等元素分布模式;刨析元素间隔、排序模式等
    208
  • 6
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(五):背景属性;float浮动和position定位;详细分析相对、绝对、固定三种定位方式;使用浮动并清除浮动副作用
    230
  • 7
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(四):元素盒子模型;详细分析边框属性、盒子外边距
    121
  • 8
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(三):元素继承关系、层叠样式规则、字体属性、文本属性;针对字体和文本作样式修改
    61
  • 9
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(二):CSS伪类:UI伪类、结构化伪类;通过伪类获得子元素的第n个元素;创建一个伪元素展示在页面中;获得最后一个元素;处理聚焦元素的样式
    116
  • 10
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(一):CSS发展史;CSS样式表的引入;CSS选择器使用,附带案例介绍
    154