From ab39ac8cc76a8c26c3917d4d1f3aa5775ed10bf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=87=E5=A4=A9?= Date: Wed, 7 Oct 2020 13:19:08 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E6=97=A5=E5=BF=97=E6=A8=A1?= =?UTF-8?q?=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 12 +++++++++ LICENSE | 21 ++++++++++++++++ Readme.md | 35 ++++++++++++++++++++++++++ index.js | 53 ++++++++++++++++++++++++++++++++++++++++ logs.js | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++ package.json | 14 +++++++++++ queue.js | 28 +++++++++++++++++++++ 7 files changed, 232 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 Readme.md create mode 100644 index.js create mode 100644 logs.js create mode 100644 package.json create mode 100644 queue.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..351c0c3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ + +.Spotlight-V100 +.Trashes +.DS_Store +.AppleDouble +.LSOverride +._* +.idea +.vscode + + +node_modules/ \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..ab60297 --- /dev/null +++ b/LICENSE @@ -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. diff --git a/Readme.md b/Readme.md new file mode 100644 index 0000000..5907a3a --- /dev/null +++ b/Readme.md @@ -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``) ++ .warn(msg``) ++ .error(msg``) + + diff --git a/index.js b/index.js new file mode 100644 index 0000000..0908974 --- /dev/null +++ b/index.js @@ -0,0 +1,53 @@ +/** + * 日志记录 + * @author yutent + * @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 }) + } + } + } +} diff --git a/logs.js b/logs.js new file mode 100644 index 0000000..5d827b6 --- /dev/null +++ b/logs.js @@ -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) diff --git a/package.json b/package.json new file mode 100644 index 0000000..c02f155 --- /dev/null +++ b/package.json @@ -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" +} diff --git a/queue.js b/queue.js new file mode 100644 index 0000000..9327a40 --- /dev/null +++ b/queue.js @@ -0,0 +1,28 @@ +/** + * 简易版队列 + * @author yutent + * @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)