完成日志模块
commit
ab39ac8cc7
|
@ -0,0 +1,12 @@
|
|||
|
||||
.Spotlight-V100
|
||||
.Trashes
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
._*
|
||||
.idea
|
||||
.vscode
|
||||
|
||||
|
||||
node_modules/
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2018
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
|
@ -0,0 +1,35 @@
|
|||
![module info](https://nodei.co/npm/@gm5/logs.png?downloads=true&downloadRank=true&stars=true)
|
||||
|
||||
# @gm5/logs
|
||||
|
||||
> 日志存储拓展。
|
||||
|
||||
## 安装
|
||||
|
||||
```bash
|
||||
npm install @gm5/logs
|
||||
```
|
||||
|
||||
## 使用
|
||||
|
||||
```js
|
||||
import Logs from '@gm5/logs'
|
||||
|
||||
// 安装时传入日志目录
|
||||
app.install(Logs, './data/logs')
|
||||
|
||||
|
||||
app.$$logs.info('hello world')
|
||||
|
||||
```
|
||||
|
||||
|
||||
## API
|
||||
|
||||
安装之后, 有3个对外的方法, 对应3个等级的日志, 即
|
||||
|
||||
+ .info(msg`<String>`)
|
||||
+ .warn(msg`<String>`)
|
||||
+ .error(msg`<String>`)
|
||||
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
/**
|
||||
* 日志记录
|
||||
* @author yutent<yutent.io@gmail.com>
|
||||
* @date 2020/10/06 20:20:30
|
||||
*/
|
||||
|
||||
import { fork } from 'child_process'
|
||||
import url from 'url'
|
||||
import path from 'path'
|
||||
|
||||
var __dirname = path.dirname(url.fileURLToPath(import.meta.url))
|
||||
var child = fork(path.join(__dirname, 'logs.js'))
|
||||
|
||||
export default {
|
||||
name: 'logs',
|
||||
install(dir) {
|
||||
// 在初始化之前写入的日志, 会失败, 所以要先扔进临时队列中
|
||||
// 初始化之后再写入
|
||||
var queue = []
|
||||
var ready = false
|
||||
|
||||
child.on('message', _ => {
|
||||
child.send({ type: 'init', dir })
|
||||
ready = true
|
||||
post()
|
||||
})
|
||||
|
||||
// 发送日志
|
||||
function post(item) {
|
||||
if (item) {
|
||||
queue.push(item)
|
||||
}
|
||||
|
||||
if (ready) {
|
||||
while (queue.length) {
|
||||
child.send(queue.shift())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
info(msg) {
|
||||
post({ type: 'info', msg })
|
||||
},
|
||||
warn(msg) {
|
||||
post({ type: 'warn', msg })
|
||||
},
|
||||
error(msg) {
|
||||
post({ type: 'error', msg })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
|
||||
import Queue from './queue.js'
|
||||
|
||||
var list = new Queue()
|
||||
var file
|
||||
var currSize = 0
|
||||
var ws
|
||||
var ready = false
|
||||
|
||||
list.on('data', _ => {
|
||||
while (list.size) {
|
||||
ws.write(list.shift())
|
||||
}
|
||||
})
|
||||
|
||||
process.on('message', _ => {
|
||||
//
|
||||
switch (_.type) {
|
||||
case 'init':
|
||||
file = path.resolve(_.dir, 'app_debug.log')
|
||||
ws = fs.createWriteStream(file, { flags: 'a' })
|
||||
ws.once('ready', _ => {
|
||||
ready = true
|
||||
list.emit('data')
|
||||
currSize = fs.statSync(file).size
|
||||
})
|
||||
break
|
||||
default:
|
||||
var now = new Date().toISOString()
|
||||
var data = `[${_.type}] ${now} ${_.msg}\n`
|
||||
var len = Buffer.byteLength(data)
|
||||
var id = 1
|
||||
|
||||
list.append(data)
|
||||
|
||||
if (ready) {
|
||||
// 日志文件大于512MB, 自动分割文件
|
||||
if (currSize + len > 1024 * 1024 * 512) {
|
||||
ready = false
|
||||
ws.close()
|
||||
|
||||
try {
|
||||
// fs.constants.F_OK
|
||||
while (fs.accessSync(`${file}.${id}`, 0) === undefined) {
|
||||
id++
|
||||
}
|
||||
} catch (e) {}
|
||||
|
||||
fs.renameSync(file, `${file}.${id}`)
|
||||
ws = fs.createWriteStream(file, { flags: 'a' })
|
||||
|
||||
currSize = len
|
||||
ws.once('ready', _ => {
|
||||
ready = true
|
||||
list.emit('data')
|
||||
})
|
||||
} else {
|
||||
currSize += len
|
||||
list.emit('data')
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
})
|
||||
|
||||
// 发送一个空消息, 通知主进程已经就绪
|
||||
process.send(null)
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"name": "@gm5/logs",
|
||||
"version": "1.0.0",
|
||||
"type": "module",
|
||||
"description": "日志存储拓展",
|
||||
"main": "index.js",
|
||||
"author": "yutent",
|
||||
"keywords": [
|
||||
"fivejs",
|
||||
"logs"
|
||||
],
|
||||
"repository": "https://github.com/bytedo/gmf.logs.git",
|
||||
"license": "MIT"
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/**
|
||||
* 简易版队列
|
||||
* @author yutent<yutent.io@gmail.com>
|
||||
* @date 2020/10/07 00:22:26
|
||||
*/
|
||||
|
||||
import { EventEmitter } from 'events'
|
||||
import { inherits } from 'util'
|
||||
|
||||
export default class Queue {
|
||||
constructor() {
|
||||
this.__store__ = []
|
||||
}
|
||||
|
||||
get size() {
|
||||
return this.__store__.length
|
||||
}
|
||||
|
||||
append(item) {
|
||||
this.__store__.push(item)
|
||||
}
|
||||
|
||||
shift() {
|
||||
return this.__store__.shift()
|
||||
}
|
||||
}
|
||||
|
||||
inherits(Queue, EventEmitter)
|
Loading…
Reference in New Issue