first commit
This commit is contained in:
3
install/secu/make/node_modules/tail/.github/FUNDING.yml
generated
vendored
Normal file
3
install/secu/make/node_modules/tail/.github/FUNDING.yml
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: lucagrulla
|
7
install/secu/make/node_modules/tail/.github/dependabot.yml
generated
vendored
Normal file
7
install/secu/make/node_modules/tail/.github/dependabot.yml
generated
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: npm
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: monthly
|
||||
open-pull-requests-limit: 10
|
67
install/secu/make/node_modules/tail/.github/workflows/codeql-analysis.yml
generated
vendored
Normal file
67
install/secu/make/node_modules/tail/.github/workflows/codeql-analysis.yml
generated
vendored
Normal file
@ -0,0 +1,67 @@
|
||||
# For most projects, this workflow file will not need changing; you simply need
|
||||
# to commit it to your repository.
|
||||
#
|
||||
# You may wish to alter this file to override the set of languages analyzed,
|
||||
# or to provide custom queries or build logic.
|
||||
#
|
||||
# ******** NOTE ********
|
||||
# We have attempted to detect the languages in your repository. Please check
|
||||
# the `language` matrix defined below to confirm you have the correct set of
|
||||
# supported CodeQL languages.
|
||||
#
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [ master ]
|
||||
schedule:
|
||||
- cron: '16 13 * * 3'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: [ 'javascript' ]
|
||||
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
|
||||
# Learn more:
|
||||
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v1
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
# By default, queries listed here will override any specified in a config file.
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
# queries: ./path/to/local/query, your-org/your-repo/queries@main
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v1
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
|
||||
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
||||
# and modify them (or add more) to build your code if your project
|
||||
# uses a compiled language
|
||||
|
||||
#- run: |
|
||||
# make bootstrap
|
||||
# make release
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v1
|
21
install/secu/make/node_modules/tail/LICENSE
generated
vendored
Normal file
21
install/secu/make/node_modules/tail/LICENSE
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2011 2012 2013 Forward
|
||||
|
||||
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.
|
122
install/secu/make/node_modules/tail/README.md
generated
vendored
Normal file
122
install/secu/make/node_modules/tail/README.md
generated
vendored
Normal file
@ -0,0 +1,122 @@
|
||||
# Tail
|
||||
|
||||
The **zero** dependency Node.js module for tailing a file
|
||||
|
||||
[](https://nodei.co/npm/tail.png?downloads=true&downloadRank=true)
|
||||
|
||||
[](https://github.com/lucagrulla/node-tail/blob/master/LICENSE)
|
||||
[](https://www.npmjs.com/package/tail)
|
||||

|
||||
|
||||
Made with ❤️ by [Luca Grulla](https://www.lucagrulla.com)
|
||||
|
||||
1. TOC
|
||||
{:toc}
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
npm install tail
|
||||
```
|
||||
|
||||
## Use
|
||||
|
||||
```javascript
|
||||
Tail = require('tail').Tail;
|
||||
|
||||
tail = new Tail("fileToTail");
|
||||
|
||||
tail.on("line", function(data) {
|
||||
console.log(data);
|
||||
});
|
||||
|
||||
tail.on("error", function(error) {
|
||||
console.log('ERROR: ', error);
|
||||
});
|
||||
```
|
||||
|
||||
If you want to stop tail:
|
||||
|
||||
```javascript
|
||||
tail.unwatch()
|
||||
```
|
||||
|
||||
To start watching again:
|
||||
|
||||
```javascript
|
||||
tail.watch()
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
The only mandatory parameter is the path to the file to tail.
|
||||
|
||||
```javascript
|
||||
var fileToTail = "/path/to/fileToTail.txt";
|
||||
new Tail(fileToTail)
|
||||
```
|
||||
|
||||
If the file is **missing or invalid** ```Tail``` constructor will throw an Exception and won't initialize.
|
||||
|
||||
```javascript
|
||||
try {
|
||||
new Tail('missingFile.txt')
|
||||
} catch (ex) {
|
||||
console.log(ex)
|
||||
}
|
||||
```
|
||||
|
||||
Optional parameters can be passed via a hash:
|
||||
|
||||
```javascript
|
||||
var options= {separator: /[\r]{0,1}\n/, fromBeginning: false, fsWatchOptions: {}, follow: true, logger: console}
|
||||
new Tail(fileToTail, options)
|
||||
```
|
||||
|
||||
### Constructor parameters
|
||||
|
||||
* `separator`: the line separator token (default: `/[\r]{0,1}\n/` to handle linux/mac (9+)/windows). Pass `null` for is binary files with no line separator.
|
||||
* `fsWatchOptions`: the full set of options that can be passed to `fs.watch` as per node documentation (default: {}).
|
||||
* `fromBeginning`: tail from the beginning of the file (default: `false`). If `fromBeginning` is true `nLines` will be ignored.
|
||||
* `follow`: simulate `tail -F` option. In the case the file is moved/renamed/logrotated, if set to `true` will start tailing again after a 1 second delay; if set to `false` it will emit an error event (default: `true`).
|
||||
* `logger`: a logger object(default: no logger). The passed logger should follow the folliwing signature:
|
||||
* `info([data][, ...])`
|
||||
* `error([data][, ...])`
|
||||
* `nLines`: tail from the last n lines. (default: `undefined`). Ignored if `fromBeginning` is set to `true`.
|
||||
* `useWatchFile`: if set to `true` will force the use of `fs.watchFile` over delegating to the library the choice between `fs.watch` and `fs.watchFile` (default: `false`).
|
||||
* `encoding`: the file encoding (default:`utf-8`).
|
||||
* `flushAtEOF`: set to `true` to force flush of content when end of file is reached. Useful when there's no separator character at the end of the file (default: `false`).
|
||||
|
||||
## Emitted events
|
||||
|
||||
`Tail` emits two events:
|
||||
|
||||
* line
|
||||
|
||||
```javascript
|
||||
tail.on('line', (data) => {
|
||||
console.log(data)
|
||||
})
|
||||
```
|
||||
|
||||
* error
|
||||
|
||||
```javascript
|
||||
tail.on('error', (err) => {
|
||||
console.log(err)
|
||||
})
|
||||
```
|
||||
The error emitted is either the underline exception or a descriptive string.
|
||||
|
||||
## How to contribute
|
||||
Node Tail code repo is [here](https://github.com/lucagrulla/node-tail/)
|
||||
Tail is written in ES6. Pull Requests are welcome.
|
||||
|
||||
## History
|
||||
|
||||
Tail was born as part of a data firehose. Read more about that project [here](https://www.lucagrulla.com/posts/building-a-firehose-with-nodejs/).
|
||||
Tail originally was written in [CoffeeScript](https://coffeescript.org/). Since December 2020 it's pure ES6.
|
||||
|
||||
## License
|
||||
|
||||
MIT. Please see [License](https://github.com/lucagrulla/node-tail/blob/master/LICENSE) file for more details.
|
233
install/secu/make/node_modules/tail/lib/tail.js
generated
vendored
Normal file
233
install/secu/make/node_modules/tail/lib/tail.js
generated
vendored
Normal file
@ -0,0 +1,233 @@
|
||||
let events = require(`events`)
|
||||
let fs = require('fs')
|
||||
let path = require('path')
|
||||
|
||||
// const environment = process.env['NODE_ENV'] || 'development'
|
||||
|
||||
class devNull {
|
||||
info() { };
|
||||
error() { };
|
||||
};
|
||||
|
||||
class Tail extends events.EventEmitter {
|
||||
|
||||
constructor(filename, options = {}) {
|
||||
super();
|
||||
this.filename = filename;
|
||||
this.absPath = path.dirname(this.filename);
|
||||
this.separator = (options.separator !== undefined) ? options.separator : /[\r]{0,1}\n/;// null is a valid param
|
||||
this.fsWatchOptions = options.fsWatchOptions || {};
|
||||
this.follow = options['follow'] != undefined ? options['follow'] : true;
|
||||
this.logger = options.logger || new devNull();
|
||||
this.useWatchFile = options.useWatchFile || false;
|
||||
this.flushAtEOF = options.flushAtEOF || false;
|
||||
this.encoding = options.encoding || 'utf-8';
|
||||
const fromBeginning = options.fromBeginning || false;
|
||||
this.nLines = options.nLines || undefined;
|
||||
|
||||
this.logger.info(`Tail starting...`)
|
||||
this.logger.info(`filename: ${this.filename}`);
|
||||
this.logger.info(`encoding: ${this.encoding}`);
|
||||
|
||||
try {
|
||||
fs.accessSync(this.filename, fs.constants.F_OK);
|
||||
} catch (err) {
|
||||
if (err.code == 'ENOENT') {
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
this.buffer = '';
|
||||
this.internalDispatcher = new events.EventEmitter();
|
||||
this.queue = [];
|
||||
this.isWatching = false;
|
||||
this.pos = 0;
|
||||
|
||||
// this.internalDispatcher.on('next',this.readBlock);
|
||||
this.internalDispatcher.on('next', () => {
|
||||
this.readBlock();
|
||||
});
|
||||
|
||||
this.logger.info(`fromBeginning: ${fromBeginning}`);
|
||||
let startingCursor;
|
||||
if (fromBeginning) {
|
||||
startingCursor = 0;
|
||||
} else if (this.nLines !== undefined) {
|
||||
const data = fs.readFileSync(this.filename, {
|
||||
flag: 'r',
|
||||
encoding: this.encoding
|
||||
});
|
||||
const tokens = data.split(this.separator);
|
||||
const dropLastToken = (tokens[tokens.length - 1] === '') ? 1 : 0;//if the file ends with empty line ignore line NL
|
||||
if (tokens.length - this.nLines - dropLastToken <= 0) {
|
||||
//nLines is bigger than avaiable tokens: tail from the begin
|
||||
startingCursor = 0;
|
||||
} else {
|
||||
const match = data.match(new RegExp(`(?:[^\r\n]*[\r]{0,1}\n){${tokens.length - this.nLines - dropLastToken}}`));
|
||||
startingCursor = (match && match.length) ? Buffer.byteLength(match[0], this.encoding) : this.latestPosition();
|
||||
}
|
||||
} else {
|
||||
startingCursor = this.latestPosition();
|
||||
}
|
||||
if (startingCursor === undefined) throw new Error("Tail can't initialize.");
|
||||
const flush = fromBeginning || (this.nLines != undefined);
|
||||
try {
|
||||
this.watch(startingCursor, flush);
|
||||
} catch (err) {
|
||||
this.logger.error(`watch for ${this.filename} failed: ${err}`);
|
||||
this.emit("error", `watch for ${this.filename} failed: ${err}`);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
latestPosition() {
|
||||
try {
|
||||
return fs.statSync(this.filename).size;
|
||||
} catch (err) {
|
||||
this.logger.error(`size check for ${this.filename} failed: ${err}`);
|
||||
this.emit("error", `size check for ${this.filename} failed: ${err}`);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
readBlock() {
|
||||
if (this.queue.length >= 1) {
|
||||
const block = this.queue[0];
|
||||
if (block.end > block.start) {
|
||||
let stream = fs.createReadStream(this.filename, { start: block.start, end: block.end - 1, encoding: this.encoding });
|
||||
stream.on('error', (error) => {
|
||||
this.logger.error(`Tail error: ${error}`);
|
||||
this.emit('error', error);
|
||||
});
|
||||
stream.on('end', () => {
|
||||
let _ = this.queue.shift();
|
||||
if (this.queue.length > 0) {
|
||||
this.internalDispatcher.emit('next');
|
||||
}
|
||||
if (this.flushAtEOF && this.buffer.length > 0) {
|
||||
this.emit('line', this.buffer);
|
||||
this.buffer = "";
|
||||
}
|
||||
});
|
||||
stream.on('data', (d) => {
|
||||
if (this.separator === null) {
|
||||
this.emit("line", d);
|
||||
} else {
|
||||
this.buffer += d;
|
||||
let parts = this.buffer.split(this.separator);
|
||||
this.buffer = parts.pop();
|
||||
for (const chunk of parts) {
|
||||
this.emit("line", chunk);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
change() {
|
||||
let p = this.latestPosition()
|
||||
if (p < this.currentCursorPos) {//scenario where text is not appended but it's actually a w+
|
||||
this.currentCursorPos = p
|
||||
} else if (p > this.currentCursorPos) {
|
||||
this.queue.push({ start: this.currentCursorPos, end: p });
|
||||
this.currentCursorPos = p
|
||||
if (this.queue.length == 1) {
|
||||
this.internalDispatcher.emit("next");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
watch(startingCursor, flush) {
|
||||
if (this.isWatching) return;
|
||||
this.logger.info(`filesystem.watch present? ${fs.watch != undefined}`);
|
||||
this.logger.info(`useWatchFile: ${this.useWatchFile}`);
|
||||
|
||||
this.isWatching = true;
|
||||
this.currentCursorPos = startingCursor;
|
||||
//force a file flush is either fromBegining or nLines flags were passed.
|
||||
if (flush) this.change();
|
||||
|
||||
if (!this.useWatchFile && fs.watch) {
|
||||
this.logger.info(`watch strategy: watch`);
|
||||
this.watcher = fs.watch(this.filename, this.fsWatchOptions, (e, filename) => { this.watchEvent(e, filename); });
|
||||
} else {
|
||||
this.logger.info(`watch strategy: watchFile`);
|
||||
fs.watchFile(this.filename, this.fsWatchOptions, (curr, prev) => { this.watchFileEvent(curr, prev) });
|
||||
}
|
||||
}
|
||||
|
||||
rename(filename) {
|
||||
//TODO
|
||||
//MacOS sometimes throws a rename event for no reason.
|
||||
//Different platforms might behave differently.
|
||||
//see https://nodejs.org/api/fs.html#fs_fs_watch_filename_options_listener
|
||||
//filename might not be present.
|
||||
//https://nodejs.org/api/fs.html#fs_filename_argument
|
||||
//Better solution would be check inode but it will require a timeout and
|
||||
// a sync file read.
|
||||
if (filename === undefined || filename !== this.filename) {
|
||||
this.unwatch();
|
||||
if (this.follow) {
|
||||
this.filename = path.join(this.absPath, filename);
|
||||
this.rewatchId = setTimeout((() => {
|
||||
try {
|
||||
this.watch(this.currentCursorPos);
|
||||
} catch (ex) {
|
||||
this.logger.error(`'rename' event for ${this.filename}. File not available anymore.`);
|
||||
this.emit("error", ex);
|
||||
}
|
||||
}), 1000);
|
||||
} else {
|
||||
this.logger.error(`'rename' event for ${this.filename}. File not available anymore.`);
|
||||
this.emit("error", `'rename' event for ${this.filename}. File not available anymore.`);
|
||||
}
|
||||
} else {
|
||||
// this.logger.info("rename event but same filename")
|
||||
}
|
||||
}
|
||||
|
||||
watchEvent(e, evtFilename) {
|
||||
try {
|
||||
if (e === 'change') {
|
||||
this.change();
|
||||
} else if (e === 'rename') {
|
||||
this.rename(evtFilename);
|
||||
}
|
||||
} catch (err) {
|
||||
this.logger.error(`watchEvent for ${this.filename} failed: ${err}`);
|
||||
this.emit("error", `watchEvent for ${this.filename} failed: ${err}`);
|
||||
}
|
||||
}
|
||||
|
||||
watchFileEvent(curr, prev) {
|
||||
if (curr.size > prev.size) {
|
||||
this.currentCursorPos = curr.size; //Update this.currentCursorPos so that a consumer can determine if entire file has been handled
|
||||
this.queue.push({ start: prev.size, end: curr.size });
|
||||
if (this.queue.length == 1) {
|
||||
this.internalDispatcher.emit("next");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unwatch() {
|
||||
if (this.watcher) {
|
||||
this.watcher.close();
|
||||
} else {
|
||||
fs.unwatchFile(this.filename);
|
||||
}
|
||||
if (this.rewatchId) {
|
||||
clearTimeout(this.rewatchId);
|
||||
this.rewatchId = undefined;
|
||||
}
|
||||
this.isWatching = false;
|
||||
this.queue = [];// TODO: is this correct behaviour?
|
||||
if (this.logger) {
|
||||
this.logger.info(`Unwatch ${this.filename}`);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
exports.Tail = Tail
|
40
install/secu/make/node_modules/tail/package.json
generated
vendored
Normal file
40
install/secu/make/node_modules/tail/package.json
generated
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
{
|
||||
"author": {
|
||||
"name": "Luca Grulla",
|
||||
"url": "https://www.lucagrulla.com"
|
||||
},
|
||||
"contributors": [
|
||||
"Luca Grulla",
|
||||
"Tom Hall"
|
||||
],
|
||||
"name": "tail",
|
||||
"description": "tail a file in node",
|
||||
"keywords": [
|
||||
"tail",
|
||||
"file",
|
||||
"logs"
|
||||
],
|
||||
"version": "2.2.4",
|
||||
"homepage": "https://www.lucagrulla.com/node-tail",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/lucagrulla/node-tail.git"
|
||||
},
|
||||
"main": "lib/tail",
|
||||
"engines": {
|
||||
"node": ">= 6.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "rm -f ./lib/** && cp src/tail.js ./lib/",
|
||||
"prepare": "npm run build",
|
||||
"prepublishOnly": "npm run test",
|
||||
"test": "mocha",
|
||||
"coverage": "nyc npm run test"
|
||||
},
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"chai": "4.x",
|
||||
"mocha": "9.x",
|
||||
"nyc": "^15.1.0"
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user