Squashed 'src/deps/src/lualogging/' content from commit 465c99478
git-subtree-dir: src/deps/src/lualogging git-subtree-split: 465c994788f1bc18fca950934fa5ec9a909f496c
This commit is contained in:
commit
2d86912af8
|
@ -0,0 +1,20 @@
|
|||
root = true
|
||||
|
||||
[*]
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
charset = utf-8
|
||||
|
||||
[*.lua]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.html]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[Makefile]
|
||||
indent_style = tab
|
||||
trim_trailing_whitespace = true
|
|
@ -0,0 +1,34 @@
|
|||
name: Deploy
|
||||
|
||||
on: [ push, workflow_dispatch ]
|
||||
|
||||
jobs:
|
||||
|
||||
affected:
|
||||
uses: lunarmodules/.github/.github/workflows/list_affected_rockspecs.yml@main
|
||||
|
||||
build:
|
||||
needs: affected
|
||||
if: ${{ needs.affected.outputs.rockspecs }}
|
||||
uses: lunarmodules/.github/.github/workflows/test_build_rock.yml@main
|
||||
with:
|
||||
rockspecs: ${{ needs.affected.outputs.rockspecs }}
|
||||
|
||||
upload:
|
||||
needs: [ affected, build ]
|
||||
# Only run upload if:
|
||||
# 1. We are on the canonical repository (no uploads from forks)
|
||||
# 2. The current commit is either tagged or on the default branch (the workflow will upload dev/scm rockspecs any
|
||||
# time they are touched, tagged ones whenever the edited rockspec and tag match)
|
||||
# 3. Some rockspecs were changed — this implies the commit changing the rockspec is the same one that gets tagged
|
||||
if: >-
|
||||
${{
|
||||
github.repository == 'lunarmodules/lualogging' &&
|
||||
( github.ref_name == 'master' || startsWith(github.ref, 'refs/tags/') ) &&
|
||||
needs.affected.outputs.rockspecs
|
||||
}}
|
||||
uses: lunarmodules/.github/.github/workflows/upload_to_luarocks.yml@main
|
||||
with:
|
||||
rockspecs: ${{ needs.affected.outputs.rockspecs }}
|
||||
secrets:
|
||||
apikey: ${{ secrets.LUAROCKS_APIKEY }}
|
|
@ -0,0 +1,13 @@
|
|||
name: Luacheck
|
||||
|
||||
on: [ push, pull_request ]
|
||||
|
||||
jobs:
|
||||
|
||||
luacheck:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Luacheck
|
||||
uses: lunarmodules/luacheck@v0
|
|
@ -0,0 +1,34 @@
|
|||
name: Test
|
||||
|
||||
on: [ push, pull_request ]
|
||||
|
||||
jobs:
|
||||
|
||||
test:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
luaVersion: [ "5.4", "5.3", "5.2", "5.1", "luajit" ] # , "luajit-openresty" ]
|
||||
debug: ["", "_G.debug = nil"] # also run with debug lib disabled
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Setup ‘lua’
|
||||
uses: leafo/gh-actions-lua@v9
|
||||
with:
|
||||
luaVersion: ${{ matrix.luaVersion }}
|
||||
|
||||
- name: Setup ‘luarocks’
|
||||
uses: leafo/gh-actions-luarocks@v4
|
||||
|
||||
- name: Setup dependencies
|
||||
run: |
|
||||
luarocks install luasocket
|
||||
|
||||
|
||||
- name: Run regression tests
|
||||
run: make test
|
||||
env:
|
||||
LUA_INIT: ${{ matrix.debug }}
|
|
@ -0,0 +1,2 @@
|
|||
tests/test.log*
|
||||
*.rock
|
|
@ -0,0 +1,34 @@
|
|||
--std = "ngx_lua+busted"
|
||||
unused_args = false
|
||||
redefined = false
|
||||
max_line_length = false
|
||||
|
||||
|
||||
globals = {
|
||||
--"_KONG",
|
||||
--"kong",
|
||||
--"ngx.IS_CLI",
|
||||
}
|
||||
|
||||
|
||||
not_globals = {
|
||||
"string.len",
|
||||
"table.getn",
|
||||
}
|
||||
|
||||
|
||||
ignore = {
|
||||
--"6.", -- ignore whitespace warnings
|
||||
}
|
||||
|
||||
|
||||
exclude_files = {
|
||||
-- The Github Actions Lua Environment
|
||||
".lua",
|
||||
".luarocks",
|
||||
".install",
|
||||
}
|
||||
|
||||
files["src/logging/nginx.lua"] = {
|
||||
std = "+ngx_lua"
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
Copyright (c) 2004-2010 Kepler Project, 2011-2013 Neopallium, 2020-2023 Thijs Schreijer
|
||||
|
||||
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,22 @@
|
|||
# Default prefix
|
||||
PREFIX = /usr/local
|
||||
|
||||
# System's lua directory (where Lua libraries are installed)
|
||||
LUA_DIR= $(PREFIX)/share/lua/5.1
|
||||
|
||||
LUAS= src/logging/console.lua src/logging/email.lua src/logging/file.lua src/logging/rolling_file.lua src/logging/socket.lua src/logging/sql.lua src/logging/nginx.lua src/logging/rsyslog.lua src/logging/envconfig.lua
|
||||
ROOT_LUAS= src/logging.lua
|
||||
|
||||
build clean:
|
||||
|
||||
install:
|
||||
mkdir -p $(LUA_DIR)/logging
|
||||
cp $(LUAS) $(LUA_DIR)/logging
|
||||
cp $(ROOT_LUAS) $(LUA_DIR)
|
||||
|
||||
test:
|
||||
cd tests && ./run_tests.sh
|
||||
cd tests && LUA_INIT="_G.debug = nil" ./run_tests.sh
|
||||
|
||||
lint:
|
||||
luacheck .
|
|
@ -0,0 +1,12 @@
|
|||
|
||||
LUA_DIR= c:\lua5.1\lua
|
||||
|
||||
LUAS= src\logging\console.lua src\logging\email.lua src\logging\file.lua src\logging\rolling_file.lua src\logging\socket.lua src\logging\sql.lua src/logging/nginx.lua src/logging/rsyslog.lua src/logging/envconfig.lua
|
||||
ROOT_LUAS= src\logging.lua
|
||||
|
||||
build clean:
|
||||
|
||||
install:
|
||||
IF NOT EXIST $(LUA_DIR)\logging mkdir $(LUA_DIR)\logging
|
||||
FOR %i IN ($(LUAS)) DO copy %i $(LUA_DIR)\logging
|
||||
FOR %i IN ($(ROOT_LUAS)) DO copy %i $(LUA_DIR)
|
|
@ -0,0 +1,63 @@
|
|||
LuaLogging
|
||||
==========
|
||||
|
||||
[![Test](https://img.shields.io/github/actions/workflow/status/lunarmodules/lualogging/test.yml?label=Test&branch=master&logo=linux)](https://github.com/lunarmodules/lualogging/actions?workflow=Test)
|
||||
[![Luacheck](https://img.shields.io/github/actions/workflow/status/lunarmodules/lualogging/luacheck.yml?label=Luacheck&logo=Lua&branch=master)](https://github.com/lunarmodules/lualogging/actions?workflow=Luacheck)
|
||||
[![GitHub tag (latest SemVer)](https://img.shields.io/github/v/tag/lunarmodules/lualogging?logo=semver)](https://github.com/lunarmodules/lualogging/releases)
|
||||
[![Luarocks](https://img.shields.io/luarocks/v/tieske/lualogging?label=Luarocks&logo=Lua)](https://luarocks.org/modules/tieske/lualogging)
|
||||
|
||||
https://lunarmodules.github.io/lualogging/
|
||||
|
||||
LuaLogging provides a simple API to use logging features in Lua.
|
||||
Its design was based on log4j. LuaLogging currently supports,
|
||||
through the use of appenders, console, file, rolling file, email, socket and sql outputs.
|
||||
|
||||
LuaLogging is free software and uses the same license as Lua. It is part of the Kepler Project.
|
||||
|
||||
Please see docs at https://lunarmodules.github.io/lualogging/ for more details
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
With LuaRocks:
|
||||
|
||||
```sh
|
||||
luarocks install lualogging
|
||||
```
|
||||
|
||||
Latest Git revision
|
||||
-------------------
|
||||
|
||||
With LuaRocks:
|
||||
|
||||
```sh
|
||||
luarocks install lualogging --dev
|
||||
```
|
||||
|
||||
With make:
|
||||
|
||||
```sh
|
||||
sudo make
|
||||
```
|
||||
|
||||
Copyright
|
||||
=========
|
||||
|
||||
See [LICENSE file](https://github.com/lunarmodules/lualogging/blob/master/COPYRIGHT)
|
||||
|
||||
History and changelog
|
||||
=====================
|
||||
|
||||
For the changelog see the [online documentation](https://lunarmodules.github.io/lualogging/index.html#history).
|
||||
|
||||
### Releasing a new version
|
||||
|
||||
- update changelog in docs (`index.html`, update `history` and `status` sections)
|
||||
- update version in `logging.lua`
|
||||
- update copyright years if needed
|
||||
- update rockspec
|
||||
- commit as `release X.Y.Z`
|
||||
- tag as `vX.Y.Z`
|
||||
- push commit and tag
|
||||
- upload to luarocks
|
||||
- test luarocks installation
|
|
@ -0,0 +1,153 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"https://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="https://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<title>LuaLogging: A simple API to use logging features in Lua</title>
|
||||
<link rel="stylesheet" href="doc.css" type="text/css"/>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="container">
|
||||
|
||||
<div id="product">
|
||||
<div id="product_logo">
|
||||
<img alt="LuaLogging logo" src="images/lualogging-128.png"/>
|
||||
</div>
|
||||
<div id="product_name"><big><strong>LuaLogging</strong></big></div>
|
||||
<div id="product_description">A simple API to use logging features in Lua.</div>
|
||||
</div> <!-- id="product" -->
|
||||
|
||||
<div id="main">
|
||||
|
||||
<div id="navigation">
|
||||
<h1>LuaLogging</h1>
|
||||
<ul>
|
||||
<li><a href="index.html">Home</a></li>
|
||||
<li><a href="manual.html">Manual</a>
|
||||
<ul>
|
||||
<li><a href="manual.html#installation">Installation</a></li>
|
||||
<li><a href="manual.html#logger">Logger objects</a></li>
|
||||
<li><a href="manual.html#examples">Examples</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="manual.html#appenders">Appenders</a>
|
||||
<ul>
|
||||
<li><strong>Console</strong></li>
|
||||
<li><a href="file.html">File</a></li>
|
||||
<li><a href="rolling_file.html">Rolling File</a></li>
|
||||
<li><a href="sql.html">SQL</a></li>
|
||||
<li><a href="socket.html">Socket</a></li>
|
||||
<li><a href="rsyslog.html">Rsyslog</a></li>
|
||||
<li><a href="email.html">Email</a></li>
|
||||
<li><a href="nginx.html">Nginx</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="https://github.com/lunarmodules/lualogging">Project</a></li>
|
||||
<li><a href="license.html">License</a></li>
|
||||
</ul>
|
||||
</div> <!-- id="navigation" -->
|
||||
|
||||
<div id="content">
|
||||
|
||||
<h2>Console appender</h2>
|
||||
|
||||
<p>Console is the simplest appender. It just writes the log messages
|
||||
to <code>io.stdout</code> or <code>io.stderr</code>.</p>
|
||||
|
||||
<pre class="example">
|
||||
function logging.console {
|
||||
[destination = "stdout"|"stderr",]
|
||||
|
||||
[logPattern = <i>string</i>,]
|
||||
[logPatterns = {
|
||||
[logging.DEBUG = <i>string</i>,]
|
||||
[logging.INFO = <i>string</i>,]
|
||||
[logging.WARN = <i>string</i>,]
|
||||
[logging.ERROR = <i>string</i>,]
|
||||
[logging.FATAL = <i>string</i>,]
|
||||
},]
|
||||
[timestampPattern = <i>string</i>,]
|
||||
[logLevel = <i>log-level-constant</i>,]
|
||||
}
|
||||
</pre>
|
||||
|
||||
<ul>
|
||||
<li><code>logPatterns</code>:<br />
|
||||
A table with logPattern strings indexed by the log-levels.
|
||||
A logPattern specifies how the message is written.<br />
|
||||
If this parameter is omitted, a patterns table will be created with the
|
||||
parameter <code>logPattern</code> as the default value for each log-level.
|
||||
If <code>logPattern</code> also is omitted then each level will fall back to
|
||||
the current default setting, see <code>logging.defaultLogPatterns</code>.
|
||||
</li>
|
||||
|
||||
<li><code>logPattern</code>:<br />
|
||||
This value will be used as the default value for each log-level that was
|
||||
omitted in <code>logPatterns</code>.
|
||||
</li>
|
||||
|
||||
<li><code>timestampPattern</code>:<br />
|
||||
This is an optional parameter that can be used to specify a date/time formatting
|
||||
in the log message.
|
||||
See <code>logging.date</code> for the format.
|
||||
The default is taken from <code>logging.defaultTimestampPattern()</code>.</li>
|
||||
|
||||
<li><code>destination</code>:<br />
|
||||
The destination stream, optional. The value can be either <code>"stdout"</code>,
|
||||
or <code>"stderr"</code>. The default is <code>stdout</code>.</li>
|
||||
|
||||
<li><code>logLevel</code>:<br />
|
||||
The initial log-level to set for the created logger.</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<h2>Examples</h2>
|
||||
|
||||
<pre class="example">
|
||||
local ansicolors = require("ansicolors") -- https://github.com/kikito/ansicolors.lua
|
||||
local ll = require("logging")
|
||||
require "logging.console"
|
||||
|
||||
-- set up the default logger to stderr + colorization
|
||||
ll.defaultLogger(ll.console {
|
||||
logLevel = ll.DEBUG,
|
||||
destination = "stderr",
|
||||
timestampPattern = "%y-%m-%d %H:%M:%S",
|
||||
logPatterns = {
|
||||
[ll.DEBUG] = ansicolors("%date%{cyan} %level %message %{reset}(%source)\n"),
|
||||
[ll.INFO] = ansicolors("%date %level %message\n"),
|
||||
[ll.WARN] = ansicolors("%date%{yellow} %level %message\n"),
|
||||
[ll.ERROR] = ansicolors("%date%{red bright} %level %message %{reset}(%source)\n"),
|
||||
[ll.FATAL] = ansicolors("%date%{magenta bright} %level %message %{reset}(%source)\n"),
|
||||
}
|
||||
})
|
||||
|
||||
local log = ll.defaultLogger()
|
||||
|
||||
log:info("logging.console test")
|
||||
log:debug("debugging...")
|
||||
log:error("error!")
|
||||
</pre>
|
||||
|
||||
<p> </p>
|
||||
<p> </p>
|
||||
<p> </p>
|
||||
<p> </p>
|
||||
<p> </p>
|
||||
<p> </p>
|
||||
<p> </p>
|
||||
|
||||
</div> <!-- id="content" -->
|
||||
|
||||
</div> <!-- id="main" -->
|
||||
|
||||
<div id="about">
|
||||
<p><a href="https://validator.w3.org/check?uri=referer">
|
||||
<img src="https://www.w3.org/Icons/valid-xhtml10" alt="XHTML 1.0 válido!" height="31" width="88" /></a></p>
|
||||
</div> <!-- id="about" -->
|
||||
|
||||
</div> <!-- id="container" -->
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,209 @@
|
|||
body {
|
||||
color: #47555c;
|
||||
font-size: 16px;
|
||||
font-family: "Open Sans", sans-serif;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: #eff4ff;
|
||||
}
|
||||
|
||||
a:link { color: #008fee; }
|
||||
a:visited { color: #008fee; }
|
||||
a:hover { color: #22a7ff; }
|
||||
|
||||
h1 { font-size:26px; }
|
||||
h2 { font-size:24px; }
|
||||
h3 { font-size:18px; }
|
||||
h4 { font-size:16px; }
|
||||
|
||||
hr {
|
||||
height: 1px;
|
||||
background: #c1cce4;
|
||||
border: 0px;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: "Open Sans Mono", "Andale Mono", monospace;
|
||||
}
|
||||
|
||||
tt {
|
||||
font-family: "Open Sans Mono", "Andale Mono", monospace;
|
||||
}
|
||||
|
||||
body, td, th {
|
||||
}
|
||||
|
||||
textarea, pre, tt {
|
||||
font-family: "Open Sans Mono", "Andale Mono", monospace;
|
||||
}
|
||||
|
||||
img {
|
||||
border-width: 0px;
|
||||
}
|
||||
|
||||
.example {
|
||||
background-color: #323744;
|
||||
color: white;
|
||||
font-size: 16px;
|
||||
padding: 16px 24px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
div.header, div.footer {
|
||||
}
|
||||
|
||||
#container {
|
||||
}
|
||||
|
||||
#product {
|
||||
background-color: white;
|
||||
padding: 10px;
|
||||
height: 130px;
|
||||
border-bottom: solid #d3dbec 1px;
|
||||
}
|
||||
|
||||
#product big {
|
||||
font-size: 42px;
|
||||
}
|
||||
#product strong {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
#product_logo {
|
||||
float: right;
|
||||
}
|
||||
|
||||
#product_name {
|
||||
padding-top: 15px;
|
||||
padding-left: 30px;
|
||||
font-size: 42px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
#product_description {
|
||||
padding-left: 30px;
|
||||
color: #757779;
|
||||
}
|
||||
|
||||
#main {
|
||||
background: #eff4ff;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#navigation {
|
||||
width: 100%;
|
||||
background-color: rgb(44,62,103);
|
||||
padding: 10px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#navigation h1 {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#navigation a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#navigation ul li a {
|
||||
color: rgb(136, 208, 255);
|
||||
font-weight: bold;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#navigation ul li li a {
|
||||
color: rgb(136, 208, 255);
|
||||
font-weight: normal;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#navigation ul {
|
||||
display: inline;
|
||||
color: white;
|
||||
padding: 0px;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
#navigation li {
|
||||
display: inline;
|
||||
list-style-type: none;
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
#navigation li {
|
||||
padding: 10px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
#navigation li li {
|
||||
}
|
||||
|
||||
#navigation li:hover a {
|
||||
color: rgb(166, 238, 255);
|
||||
}
|
||||
|
||||
#content {
|
||||
padding: 20px;
|
||||
width: 800px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
#about {
|
||||
display: none;
|
||||
}
|
||||
|
||||
dl.reference {
|
||||
background-color: white;
|
||||
padding: 20px;
|
||||
border: solid #d3dbec 1px;
|
||||
}
|
||||
|
||||
dl.reference dt {
|
||||
padding: 5px;
|
||||
padding-top: 25px;
|
||||
color: #637bbc;
|
||||
}
|
||||
|
||||
dl.reference dl dt {
|
||||
padding-top: 5px;
|
||||
color: #637383;
|
||||
}
|
||||
|
||||
dl.reference dd {
|
||||
}
|
||||
|
||||
@media print {
|
||||
body {
|
||||
font: 10pt "Times New Roman", "TimeNR", Times, serif;
|
||||
}
|
||||
a {
|
||||
font-weight:bold; color: #004080; text-decoration: underline;
|
||||
}
|
||||
#main {
|
||||
background-color: #ffffff; border-left: 0px;
|
||||
}
|
||||
#container {
|
||||
margin-left: 2%; margin-right: 2%; background-color: #ffffff;
|
||||
}
|
||||
#content {
|
||||
margin-left: 0px; padding: 1em; border-left: 0px; border-right: 0px; background-color: #ffffff;
|
||||
}
|
||||
#navigation {
|
||||
display: none;
|
||||
}
|
||||
#product_logo {
|
||||
display: none;
|
||||
}
|
||||
#about img {
|
||||
display: none;
|
||||
}
|
||||
.example {
|
||||
font-family: "Andale Mono", monospace;
|
||||
font-size: 8pt;
|
||||
page-break-inside: avoid;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,167 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"https://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="https://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<title>LuaLogging: A simple API to use logging features in Lua</title>
|
||||
<link rel="stylesheet" href="doc.css" type="text/css"/>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="container">
|
||||
|
||||
<div id="product">
|
||||
<div id="product_logo">
|
||||
<img alt="LuaLogging logo" src="images/lualogging-128.png"/>
|
||||
</div>
|
||||
<div id="product_name"><big><strong>LuaLogging</strong></big></div>
|
||||
<div id="product_description">A simple API to use logging features in Lua.</div>
|
||||
</div> <!-- id="product" -->
|
||||
|
||||
<div id="main">
|
||||
|
||||
<div id="navigation">
|
||||
<h1>LuaLogging</h1>
|
||||
<ul>
|
||||
<li><a href="index.html">Home</a></li>
|
||||
<li><a href="manual.html">Manual</a>
|
||||
<ul>
|
||||
<li><a href="manual.html#installation">Installation</a></li>
|
||||
<li><a href="manual.html#logger">Logger objects</a></li>
|
||||
<li><a href="manual.html#examples">Examples</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="manual.html#appenders">Appenders</a>
|
||||
<ul>
|
||||
<li><a href="console.html">Console</a></li>
|
||||
<li><a href="file.html">File</a></li>
|
||||
<li><a href="rolling_file.html">Rolling File</a></li>
|
||||
<li><a href="sql.html">SQL</a></li>
|
||||
<li><a href="socket.html">Socket</a></li>
|
||||
<li><a href="rsyslog.html">Rsyslog</a></li>
|
||||
<li><strong>Email</strong></li>
|
||||
<li><a href="nginx.html">Nginx</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="https://github.com/lunarmodules/lualogging">Project</a></li>
|
||||
<li><a href="license.html">License</a></li>
|
||||
</ul>
|
||||
</div> <!-- id="navigation" -->
|
||||
|
||||
<div id="content">
|
||||
|
||||
<h2>Email appender</h2>
|
||||
|
||||
<p>This appender can be used to send log requests through email. One email
|
||||
message is sent for each log request.</p>
|
||||
|
||||
<pre class="example">
|
||||
function logging.email {
|
||||
from = <i>string</i>,
|
||||
rcpt = <i>string</i> or <i>string-table</i>,
|
||||
[user = <i>string</i>,]
|
||||
[password = <i>string</i>,]
|
||||
[server = <i>string</i>,]
|
||||
[port = <i>number</i>,]
|
||||
[domain = <i>string</i>,]
|
||||
[headers = <i>table</i>,]
|
||||
|
||||
[logPattern = <i>string</i>,]
|
||||
[logPatterns = {
|
||||
[logging.DEBUG = <i>string</i>,]
|
||||
[logging.INFO = <i>string</i>,]
|
||||
[logging.WARN = <i>string</i>,]
|
||||
[logging.ERROR = <i>string</i>,]
|
||||
[logging.FATAL = <i>string</i>,]
|
||||
},]
|
||||
[timestampPattern = <i>string</i>,]
|
||||
[logLevel = <i>log-level-constant</i>,]
|
||||
}
|
||||
</pre>
|
||||
|
||||
<ul>
|
||||
<li><code>from</code>:<br />
|
||||
The sender of the email message.</li>
|
||||
|
||||
<li><code>rcpt</code>:<br />
|
||||
The recipient of the email message. A string or a numerically indexed Lua table with strings.</li>
|
||||
|
||||
<li><code>user</code>:<br />
|
||||
User for authentication.</li>
|
||||
|
||||
<li><code>password</code>:<br />
|
||||
Password for authentication.</li>
|
||||
|
||||
<li><code>server</code>:<br />
|
||||
Server to connect to. Default is <code>"localhost"</code>.</li>
|
||||
|
||||
<li><code>port</code>:<br />
|
||||
Port to connect to. Default is <code>25</code>.</li>
|
||||
|
||||
<li><code>domain</code>:<br />
|
||||
Domain name used to greet the server. Defaults to the local
|
||||
machine host name.</li>
|
||||
|
||||
<li><code>headers.to</code>:<br />
|
||||
The recipient of the message, as an extended description.</li>
|
||||
|
||||
<li><code>headers.from</code>:<br />
|
||||
The sender of the message, as an extended description.</li>
|
||||
|
||||
<li><code>headers.subject</code>:<br />
|
||||
The subject of the message sent. This can contain patterns like
|
||||
the <code>logPattern</code> parameter.</li>
|
||||
|
||||
<li><code>logPatterns</code>:<br />
|
||||
A table with logPattern strings indexed by the log-levels.
|
||||
A logPattern specifies how the message is written.<br />
|
||||
If this parameter is omitted, a patterns table will be created with the
|
||||
parameter <code>logPattern</code> as the default value for each log-level.
|
||||
If <code>logPattern</code> also is omitted then each level will fall back to
|
||||
the current default setting, see <code>logging.defaultLogPatterns</code>.
|
||||
</li>
|
||||
|
||||
<li><code>logPattern</code>:<br />
|
||||
This value will be used as the default value for each log-level that was
|
||||
omitted in <code>logPatterns</code>.
|
||||
</li>
|
||||
|
||||
<li><code>timestampPattern</code>:<br />
|
||||
This is an optional parameter that can be used to specify a date/time formatting
|
||||
in the log message. The default is taken from <code>logging.defaultTimestampPattern()</code>.</li>
|
||||
|
||||
<li><code>logLevel</code>:<br />
|
||||
The initial log-level to set for the created logger.</li>
|
||||
</ul>
|
||||
|
||||
<h2>Example</h2>
|
||||
|
||||
<pre class="example">
|
||||
require"logging.email"
|
||||
|
||||
local logger = logging.email {
|
||||
rcpt = "mail@host.com",
|
||||
from = "mail@host.com",
|
||||
headers = {
|
||||
subject = "[%level] logging.email test",
|
||||
},
|
||||
}
|
||||
|
||||
logger:info("logging.email test")
|
||||
logger:debug("debugging...")
|
||||
logger:error("error!")
|
||||
</pre>
|
||||
|
||||
</div> <!-- id="content" -->
|
||||
|
||||
</div> <!-- id="main" -->
|
||||
|
||||
<div id="about">
|
||||
<p><a href="https://validator.w3.org/check?uri=referer">
|
||||
<img src="https://www.w3.org/Icons/valid-xhtml10" alt="XHTML 1.0 válido!" height="31" width="88" /></a></p>
|
||||
</div> <!-- id="about" -->
|
||||
|
||||
</div> <!-- id="container" -->
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,148 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"https://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="https://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<title>LuaLogging: A simple API to use logging features in Lua</title>
|
||||
<link rel="stylesheet" href="doc.css" type="text/css"/>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="container">
|
||||
|
||||
<div id="product">
|
||||
<div id="product_logo">
|
||||
<img alt="LuaLogging logo" src="images/lualogging-128.png"/>
|
||||
</div>
|
||||
<div id="product_name"><big><strong>LuaLogging</strong></big></div>
|
||||
<div id="product_description">A simple API to use logging features in Lua.</div>
|
||||
</div> <!-- id="product" -->
|
||||
|
||||
<div id="main">
|
||||
|
||||
<div id="navigation">
|
||||
<h1>LuaLogging</h1>
|
||||
<ul>
|
||||
<li><a href="index.html">Home</a></li>
|
||||
<li><a href="manual.html">Manual</a>
|
||||
<ul>
|
||||
<li><a href="manual.html#installation">Installation</a></li>
|
||||
<li><a href="manual.html#logger">Logger objects</a></li>
|
||||
<li><a href="manual.html#examples">Examples</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="manual.html#appenders">Appenders</a>
|
||||
<ul>
|
||||
<li><a href="console.html">Console</a></li>
|
||||
<li><strong>File</strong></li>
|
||||
<li><a href="rolling_file.html">Rolling File</a></li>
|
||||
<li><a href="sql.html">SQL</a></li>
|
||||
<li><a href="socket.html">Socket</a></li>
|
||||
<li><a href="rsyslog.html">Rsyslog</a></li>
|
||||
<li><a href="email.html">Email</a></li>
|
||||
<li><a href="nginx.html">Nginx</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="https://github.com/lunarmodules/lualogging">Project</a></li>
|
||||
<li><a href="license.html">License</a></li>
|
||||
</ul>
|
||||
</div> <!-- id="navigation" -->
|
||||
|
||||
<div id="content">
|
||||
|
||||
<h2>File appender</h2>
|
||||
|
||||
<p>The file appender can be used to write log messages to a file. It
|
||||
uses Lua I/O routines to do its job.</p>
|
||||
|
||||
<pre class="example">
|
||||
function logging.file {
|
||||
[filename = <i>string</i>,]
|
||||
[datePattern = <i>string</i>,]
|
||||
|
||||
[logPattern = <i>string</i>,]
|
||||
[logPatterns = {
|
||||
[logging.DEBUG = <i>string</i>,]
|
||||
[logging.INFO = <i>string</i>,]
|
||||
[logging.WARN = <i>string</i>,]
|
||||
[logging.ERROR = <i>string</i>,]
|
||||
[logging.FATAL = <i>string</i>,]
|
||||
},]
|
||||
[timestampPattern = <i>string</i>,]
|
||||
[logLevel = <i>log-level-constant</i>,]
|
||||
}
|
||||
</pre>
|
||||
|
||||
<ul>
|
||||
<li><code>filename</code>:<br />
|
||||
The name of the file to be written to. On each call to log a
|
||||
message the file is opened for appending and closed immediately.<br />
|
||||
If the file cannot be opened for appending the logging request
|
||||
returns nil and an error message.<br />
|
||||
The default value is <code>"lualogging.log"</code>.</li>
|
||||
|
||||
<li><code>datePattern</code>:<br />
|
||||
This is an optional parameter that can be used to specify a date
|
||||
pattern that will be passed to the
|
||||
<a href="https://www.lua.org/manual/5.1/manual.html#pdf-os.date"><code>os.date</code></a>
|
||||
function to compose the filename.<br />
|
||||
This is useful to create daily or monthly log files. If the user
|
||||
wants to create one log file per day he specifies a
|
||||
<code>"%Y-%m-%d"</code> pattern and a filename like
|
||||
<code>"temp%s.log"</code>.</li>
|
||||
|
||||
<li><code>logPatterns</code>:<br />
|
||||
A table with logPattern strings indexed by the log-levels.
|
||||
A logPattern specifies how the message is written.<br />
|
||||
If this parameter is omitted, a patterns table will be created with the
|
||||
parameter <code>logPattern</code> as the default value for each log-level.
|
||||
If <code>logPattern</code> also is omitted then each level will fall back to
|
||||
the current default setting, see <code>logging.defaultLogPatterns</code>.
|
||||
</li>
|
||||
|
||||
<li><code>logPattern</code>:<br />
|
||||
This value will be used as the default value for each log-level that was
|
||||
omitted in <code>logPatterns</code>.
|
||||
</li>
|
||||
|
||||
<li><code>timestampPattern</code>:<br />
|
||||
This is an optional parameter that can be used to specify a date/time formatting
|
||||
in the log message.
|
||||
See <code>logging.date</code> for the format.
|
||||
The default is taken from <code>logging.defaultTimestampPattern()</code>.</li>
|
||||
|
||||
<li><code>logLevel</code>:<br />
|
||||
The initial log-level to set for the created logger.</li>
|
||||
</ul>
|
||||
|
||||
<h2>Example</h2>
|
||||
|
||||
<pre class="example">
|
||||
require"logging.file"
|
||||
|
||||
local logger = logging.file {
|
||||
filename = "test%s.log",
|
||||
datePattern = "%Y-%m-%d",
|
||||
}
|
||||
|
||||
logger:info("logging.file test")
|
||||
logger:debug("debugging...")
|
||||
logger:error("error!")
|
||||
</pre>
|
||||
|
||||
<p> </p>
|
||||
<p> </p>
|
||||
|
||||
</div> <!-- id="content" -->
|
||||
|
||||
</div> <!-- id="main" -->
|
||||
|
||||
<div id="about">
|
||||
<p><a href="https://validator.w3.org/check?uri=referer">
|
||||
<img src="https://www.w3.org/Icons/valid-xhtml10" alt="XHTML 1.0 válido!" height="31" width="88" /></a></p>
|
||||
</div> <!-- id="about" -->
|
||||
|
||||
</div> <!-- id="container" -->
|
||||
|
||||
</body>
|
||||
</html>
|
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
|
@ -0,0 +1,232 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"https://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="https://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<title>LuaLogging: A simple API to use logging features in Lua</title>
|
||||
<link rel="stylesheet" href="doc.css" type="text/css"/>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="container">
|
||||
|
||||
<div id="product">
|
||||
<div id="product_logo">
|
||||
<img alt="LuaLogging logo" src="images/lualogging-128.png"/>
|
||||
</div>
|
||||
<div id="product_name"><big><strong>LuaLogging</strong></big></div>
|
||||
<div id="product_description">A simple API to use logging features in Lua.</div>
|
||||
</div> <!-- id="product" -->
|
||||
|
||||
<div id="main">
|
||||
|
||||
<div id="navigation">
|
||||
<h1>LuaLogging</h1>
|
||||
<ul>
|
||||
<li><strong>Home</strong></li>
|
||||
<li><a href="manual.html">Manual</a>
|
||||
<ul>
|
||||
<li><a href="manual.html#installation">Installation</a></li>
|
||||
<li><a href="manual.html#logger">Logger objects</a></li>
|
||||
<li><a href="manual.html#examples">Examples</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="manual.html#appenders">Appenders</a>
|
||||
<ul>
|
||||
<li><a href="console.html">Console</a></li>
|
||||
<li><a href="file.html">File</a></li>
|
||||
<li><a href="rolling_file.html">Rolling File</a></li>
|
||||
<li><a href="sql.html">SQL</a></li>
|
||||
<li><a href="socket.html">Socket</a></li>
|
||||
<li><a href="rsyslog.html">Rsyslog</a></li>
|
||||
<li><a href="email.html">Email</a></li>
|
||||
<li><a href="nginx.html">Nginx</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="https://github.com/lunarmodules/lualogging">Project</a></li>
|
||||
<li><a href="license.html">License</a></li>
|
||||
</ul>
|
||||
</div> <!-- id="navigation" -->
|
||||
|
||||
<div id="content">
|
||||
<h2><a name="overview"></a>Overview</h2>
|
||||
|
||||
<p>LuaLogging provides a simple API to use logging features in Lua.
|
||||
Its design was based on
|
||||
<a href="https://logging.apache.org/log4j/docs/index.html">log4j</a>.
|
||||
LuaLogging currently supports, through the use of <em><a href="manual.html#appenders">appenders</a></em>,
|
||||
console, file, email, socket and sql outputs.</p>
|
||||
|
||||
<p>
|
||||
LuaLogging is free software and uses the same <a href="license.html">license</a>
|
||||
as Lua 5.1.
|
||||
</p>
|
||||
|
||||
<h2><a name="status"></a>Status</h2>
|
||||
|
||||
<p>
|
||||
Current version is 1.8.2. It was developed for Lua 5.1+.
|
||||
</p>
|
||||
|
||||
<h2><a name="download"></a>Download</h2>
|
||||
|
||||
<p>
|
||||
LuaLogging can be downloaded from its
|
||||
<a href="https://github.com/lunarmodules/lualogging/archives/master">GitHub</a>
|
||||
downloads page or installed via LuaRocks.
|
||||
</p>
|
||||
|
||||
<h2><a name="dependencies"></a>Dependencies</h2>
|
||||
|
||||
<p>LuaLogging dependencies can be separated by the used appenders:</p>
|
||||
|
||||
<dl>
|
||||
<dt><strong>LuaLogging Core, Console and File appenders</strong></dt>
|
||||
<dd>
|
||||
<ul>
|
||||
<li><a href="https://www.lua.org">Lua 5.1+</a></li>
|
||||
</ul>
|
||||
</dd>
|
||||
|
||||
<dt><strong>Socket, Rsyslog, and Email appenders</strong></dt>
|
||||
<dd>
|
||||
<ul>
|
||||
<li><a href="http://w3.impa.br/~diego/software/luasocket/">LuaSocket</a></li>
|
||||
</ul>
|
||||
</dd>
|
||||
|
||||
<dt><strong>SQL appender</strong></dt>
|
||||
<dd>
|
||||
<ul>
|
||||
<li>LuaSQL 2.1.x</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<h2><a name="history"></a>History</h2>
|
||||
|
||||
<dl class="history">
|
||||
<dt><strong>1.8.2</strong> [27/Jan/2023]</dt>
|
||||
<dd><strong>Fix</strong>: allow to work without the debug library.</dd>
|
||||
|
||||
<dt><strong>1.8.1</strong> [23/Jan/2023]</dt>
|
||||
<dd><strong>Fix</strong>: use explicit tostring, don't rely on automatic coercion.</dd>
|
||||
<dd><strong>Fix</strong>: rsyslog appender wouldn't properly clear the socket upon an error.</dd>
|
||||
|
||||
<dt><strong>1.8.0</strong> [22/Oct/2022]</dt>
|
||||
<dd><strong>Added</strong>: new module <code>logging.envconfig</code> to allow log configuration via
|
||||
environment variables.</dd>
|
||||
<dd><strong>Refactor</strong>: refactored the appenders to be more object like. They now return a module table.</dd>
|
||||
<dd><strong>Fix</strong>: add rsyslog appender to makefile install target.</dd>
|
||||
<dd><strong>Fix</strong>: errorhandler in rsyslog was omitting 'self', and also log the failed message itself to stderr.</dd>
|
||||
<dd><strong>Fix</strong>: when using Copas and rsyslog on Lua 5.1, coxpcall is required to yield.</dd>
|
||||
<dd><strong>Fix</strong>: rsyslog; upon failure remove the closed socket from the cache to prevent the retry from using
|
||||
the closed socket.</dd>
|
||||
|
||||
<dt><strong>1.7.0</strong> [21/Sep/2022]</dt>
|
||||
<dd><strong>Added</strong>: new function <code>logging.date</code> is compatible with <code>os.date</code>
|
||||
but supports second-fractions, to be represented by <code>%q</code> placeholder in the
|
||||
<code>timestampPattern</code>.</dd>
|
||||
<dd><strong>Added</strong>: new bundled appender; "rsyslog". This logger will log in syslog format to a remote
|
||||
syslog server. It supports both BSD as well as IETF formats, and supports sending over UDP and TCP, with an option
|
||||
to use Copas for async-sending over TCP.</dd>
|
||||
|
||||
<dt><strong>1.6.0</strong> [09/Nov/2021]</dt>
|
||||
<dd><strong>Added</strong>: the <code>logPattern</code> can now be specified for each log-level individually.
|
||||
This allows use cases like only adding <code>"%source"</code> on debug level, or injecting ansi-color coding
|
||||
in for example the error log-level.</dd>
|
||||
<dd><strong>Added</strong>: new bundled appender; "nginx". This logger has no configuration options, but will
|
||||
simply pass any log messages on to the nginx log. When using LuaLogging in OpenResty, configure this logger.</dd>
|
||||
<dd><strong>Added</strong>: application level defaults. New functions <code>logging.defaultLogPatterns()</code>
|
||||
, <code>logging.defaultTimestampPattern()</code>, <code>logging.defaultLevel()</code>, and <code>logging.defaultLogger()</code>
|
||||
can be used to get/set the global application level defaults.<br/>
|
||||
Use carefully, this is global state, so only applications should set those, libraries should not.</dd>
|
||||
<dd><strong>Added</strong>: the included appenders now have an extra parameter to set
|
||||
log-level upon creation; <code>logLevel</code>.</dd>
|
||||
<dd><strong>Added</strong>: the <code>logPattern</code> can now have new placeholders:<br/>
|
||||
<code>"%file"</code> (source file), <br/>
|
||||
<code>"%line"</code> (source line), <br/>
|
||||
<code>"%function"</code> (function name), and <br/>
|
||||
<code>"%source"</code> (evaluates to <code>"%file:%line in function '%function'"</code>).</dd>
|
||||
<dd><strong>Added</strong>: the console logger has a new optional parameter "destination",
|
||||
which must be either "stderr" or "stdout" (defaults to "stdout")</dd>
|
||||
|
||||
<dt><strong>1.5.2</strong> [12/Aug/2021]</dt>
|
||||
<dd><strong>Fix</strong>: rolling-file, 'seek' can occasionally fail, handle it properly.</dd>
|
||||
|
||||
<dt><strong>1.5.1</strong> [22/Mar/2021]</dt>
|
||||
<dd><strong>Reverted</strong>: Functionality to specify custom log levels.</dd>
|
||||
|
||||
<dt><strong>1.5.0</strong> [22/Mar/2021]</dt>
|
||||
<dd><strong>Added</strong>: Functionality to specify custom log levels.</dd>
|
||||
<dd><strong>Added</strong>: Provide verbose error message when formatting fails.</dd>
|
||||
<dd><strong>Fix</strong>: disable buffering on windows files</dd>
|
||||
|
||||
<dt><strong>1.4.0</strong> [12/Aug/2020]</dt>
|
||||
<dd><strong>Fix</strong>: No more global on Lua 5.3.</dd>
|
||||
<dd><strong>Fix</strong>: Reduced log noise when changing log levels.</dd>
|
||||
<dd><strong>Added</strong>: A new log-level "off" to suspend logging.</dd>
|
||||
<dd><strong>Fix</strong>: Restored the log-level constants on the logger object.</dd>
|
||||
<dd><strong>Fix</strong>: catch exceptions when formatting log messages.</dd>
|
||||
<dd><strong>Change</strong>: creating loggers now always takes a parameters table (consistent
|
||||
across all appenders). The old parameters are now deprecated, but still
|
||||
work for backward compatibility purposes.</dd>
|
||||
<dd><strong>Added</strong>: All appenders have a new property <code>timestampPattern</code>
|
||||
to specify the format of the timestamp in the log message</dd>
|
||||
<dd><strong>Added</strong>: <code>logger:getPrint()</code> function that returns a print-like
|
||||
function, but directs all output to the logger.</dd>
|
||||
|
||||
<dt><strong>1.3.0</strong> [5/Mar/2013]</dt>
|
||||
|
||||
<dt><strong>1.2.0</strong> [20/Apr/2011]</dt>
|
||||
<dd>Improved performance of logging.</dd>
|
||||
<dd>Added Rolling File Appender.</dd>
|
||||
|
||||
<dt><strong>1.1.4</strong> [30/Oct/2007]</dt>
|
||||
<dd>Fixed bug #1719 -
|
||||
inefficient handling of file loggers (Patch by Jürgen Hötzel).</dd>
|
||||
|
||||
<dt><strong>1.1.3</strong> [08/Aug/2007]</dt>
|
||||
<dd>New makefile for Windows (using nmake) and configure script for Unix.</dd>
|
||||
|
||||
<dt><strong>1.1.2</strong> [14/Aug/2006]</dt>
|
||||
<dd>Fixed a bug found by Carlos Augusto where tostring() was being
|
||||
incorrectly used with numbers.</dd>
|
||||
|
||||
<dt><strong>1.1.1</strong> [31/Mar/2006]</dt>
|
||||
<dd></dd>
|
||||
|
||||
<dt><strong>1.1.0</strong> [12/Nov/2004]</dt>
|
||||
<dd></dd>
|
||||
|
||||
<dt><strong>1.0.0</strong> [02/Jul/2004]</dt>
|
||||
<dd></dd>
|
||||
</dl>
|
||||
|
||||
<h2><a name="credits"></a>Credits</h2>
|
||||
|
||||
<p>
|
||||
LuaLogging 1.2 and 1.3 were maintained by Robert G. Jakabosky.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
LuaLogging 1.1.x was designed by Danilo Tuler and Thiago Ponte
|
||||
and implemented by Thiago Ponte.
|
||||
</p>
|
||||
|
||||
<p>LuaLogging 1.0.0 was designed by Danilo Tuler (and log4j)
|
||||
and implemented by Danilo Tuler and André Carregal.</p>
|
||||
|
||||
</div> <!-- id="content" -->
|
||||
|
||||
</div> <!-- id="main" -->
|
||||
|
||||
<div id="about">
|
||||
<p><a href="https://validator.w3.org/check?uri=referer">
|
||||
<img src="https://www.w3.org/Icons/valid-xhtml10" alt="XHTML 1.0 válido!" height="31" width="88" /></a></p>
|
||||
</div> <!-- id="about" -->
|
||||
|
||||
</div> <!-- id="container" -->
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,118 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"https://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="https://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<title>LuaLogging: A simple API to use logging features in Lua</title>
|
||||
<link rel="stylesheet" href="doc.css" type="text/css"/>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="container">
|
||||
|
||||
<div id="product">
|
||||
<div id="product_logo">
|
||||
<img alt="LuaLogging logo" src="images/lualogging-128.png"/>
|
||||
</div>
|
||||
<div id="product_name"><big><strong>LuaLogging</strong></big></div>
|
||||
<div id="product_description">A simple API to use logging features in Lua.</div>
|
||||
</div> <!-- id="product" -->
|
||||
|
||||
<div id="main">
|
||||
|
||||
<div id="navigation">
|
||||
<h1>LuaLogging</h1>
|
||||
<ul>
|
||||
<li><a href="index.html">Home</a></li>
|
||||
<li><a href="manual.html">Manual</a>
|
||||
<ul>
|
||||
<li><a href="manual.html#installation">Installation</a></li>
|
||||
<li><a href="manual.html#logger">Logger objects</a></li>
|
||||
<li><a href="manual.html#examples">Examples</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="manual.html#appenders">Appenders</a>
|
||||
<ul>
|
||||
<li><a href="console.html">Console</a></li>
|
||||
<li><a href="file.html">File</a></li>
|
||||
<li><a href="rolling_file.html">Rolling File</a></li>
|
||||
<li><a href="sql.html">SQL</a></li>
|
||||
<li><a href="socket.html">Socket</a></li>
|
||||
<li><a href="rsyslog.html">Rsyslog</a></li>
|
||||
<li><a href="email.html">Email</a></li>
|
||||
<li><a href="nginx.html">Nginx</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="https://github.com/lunarmodules/lualogging">Project</a></li>
|
||||
<li><a href="license.html">License</a></li>
|
||||
</ul>
|
||||
</div> <!-- id="navigation" -->
|
||||
|
||||
<div id="content">
|
||||
|
||||
<h2>License</h2>
|
||||
|
||||
<p>
|
||||
LuaLogging is free software: it can be used for both academic and
|
||||
commercial purposes at absolutely no cost. There are no royalties
|
||||
or GNU-like "copyleft" restrictions. LuaLogging qualifies as <a
|
||||
href="https://www.opensource.org/docs/definition.html">Open
|
||||
Source</a> software. Its licenses are compatible with <a href=
|
||||
"https://www.gnu.org/licenses/gpl.html">GPL</a>. LuaLogging is not
|
||||
in the public domain and the Kepler Project keep its copyright. The
|
||||
legal details are below.
|
||||
</p>
|
||||
|
||||
<p>The spirit of the license is that you are free to use LuaLogging
|
||||
for any purpose at no cost without having to ask us. The only
|
||||
requirement is that if you do use LuaLogging, then you should give
|
||||
us credit by including the appropriate copyright notice somewhere
|
||||
in your product or its documentation.</p>
|
||||
|
||||
<p>The LuaLogging library is designed by Danilo Tuler and
|
||||
implemented by Danilo Tuler, Thiago Ponte and André
|
||||
Carregal. The implementation is not derived from licensed
|
||||
software.</p>
|
||||
|
||||
<hr/>
|
||||
<p>
|
||||
Copyright © 2004-2010 Kepler Project, 2011-2013 Neopallium, 2020-2023 Thijs Schreijer
|
||||
|
||||
</p>
|
||||
|
||||
<p>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:</p>
|
||||
|
||||
<p>The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.</p>
|
||||
|
||||
<p>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.</p>
|
||||
|
||||
<p> </p>
|
||||
<p> </p>
|
||||
|
||||
</div> <!-- id="content" -->
|
||||
|
||||
</div> <!-- id="main" -->
|
||||
|
||||
<div id="about">
|
||||
<p><a href="https://validator.w3.org/check?uri=referer">
|
||||
<img src="https://www.w3.org/Icons/valid-xhtml10" alt="XHTML 1.0 válido!" height="31" width="88" /></a></p>
|
||||
</div> <!-- id="about" -->
|
||||
|
||||
</div> <!-- id="container" -->
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,472 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"https://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="https://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<title>LuaLogging: A simple API to use logging features in Lua</title>
|
||||
<link rel="stylesheet" href="doc.css" type="text/css"/>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="container">
|
||||
|
||||
<div id="product">
|
||||
<div id="product_logo">
|
||||
<img alt="LuaLogging logo" src="images/lualogging-128.png"/>
|
||||
</div>
|
||||
<div id="product_name"><big><strong>LuaLogging</strong></big></div>
|
||||
<div id="product_description">A simple API to use logging features in Lua.</div>
|
||||
</div> <!-- id="product" -->
|
||||
|
||||
<div id="main">
|
||||
|
||||
<div id="navigation">
|
||||
<h1>LuaLogging</h1>
|
||||
<ul>
|
||||
<li><a href="index.html">Home</a></li>
|
||||
<li><strong>Manual</strong>
|
||||
<ul>
|
||||
<li><a href="manual.html#installation">Installation</a></li>
|
||||
<li><a href="manual.html#logger">Logger objects</a></li>
|
||||
<li><a href="manual.html#examples">Examples</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="manual.html#appenders">Appenders</a>
|
||||
<ul>
|
||||
<li><a href="console.html">Console</a></li>
|
||||
<li><a href="file.html">File</a></li>
|
||||
<li><a href="rolling_file.html">Rolling File</a></li>
|
||||
<li><a href="sql.html">SQL</a></li>
|
||||
<li><a href="socket.html">Socket</a></li>
|
||||
<li><a href="rsyslog.html">Rsyslog</a></li>
|
||||
<li><a href="email.html">Email</a></li>
|
||||
<li><a href="nginx.html">Nginx</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="https://github.com/lunarmodules/lualogging">Project</a></li>
|
||||
<li><a href="license.html">License</a></li>
|
||||
</ul>
|
||||
</div> <!-- id="navigation" -->
|
||||
|
||||
<div id="content">
|
||||
|
||||
<h2><a name="introduction"></a>Introduction</h2>
|
||||
|
||||
<p>LuaLogging provides a simple API to use logging features in Lua.
|
||||
Its design was based on
|
||||
<a href="https://logging.apache.org/log4j/docs/index.html">log4j</a>.
|
||||
LuaLogging currently supports console, file, email, socket and sql
|
||||
outputs through the use of <em><a href="#appenders">appenders</a></em>.</p>
|
||||
|
||||
<p>The <code>logging</code> module holds a <code>new</code> function to create
|
||||
new <a href="#logger"><code>logger</code></a> objects.</p>
|
||||
|
||||
<p>This logger constructor receives a function
|
||||
(known as the <em>appender</em> function)
|
||||
that will be called on each call to log a message.</p>
|
||||
|
||||
<p>An <em>appender</em> function receives three arguments:</p>
|
||||
|
||||
<ul>
|
||||
<li><strong>self</strong>: the logger object</li>
|
||||
<li><strong>level</strong>: the logging level</li>
|
||||
<li><strong>message</strong>: the message to be logged</li>
|
||||
</ul>
|
||||
<p>The logger constructor also receives a optional second argument which should
|
||||
be a table with parameters</p>
|
||||
|
||||
<h2><a name="installation"></a>Installation</h2>
|
||||
|
||||
<p>LuaLogging is installed as a regular Lua module called <code>logging</code>.</p>
|
||||
<p>installation is easiest using LuaRocks; "<code>luarocks install lualogging</code>",
|
||||
or alternatively using the <code>Makefile</code>.</p>
|
||||
|
||||
<h2><a name="logging"></a>Logging module</h2>
|
||||
|
||||
<p>The logging module has a number of global functions:</p>
|
||||
<dl class="reference">
|
||||
<dt><strong>logging.new( function[, logLevel] )</strong></dt>
|
||||
<dd>Creates a new logger object from a custom 'appender' function. See examples below.
|
||||
The appender function signature is <code>function(self, level, message)</code>. The
|
||||
optional logLevel argument specifies the initial log-level to set (the value must be
|
||||
a valid log-level constant). If omitted defaults to <code>logging.defaultLevel</code>.
|
||||
</dd>
|
||||
|
||||
<dt><strong>patts = logging.buildLogPatterns([table], [string])</strong></dt>
|
||||
<dd>Creates a log-patterns table. The returned table will for each level have
|
||||
the logPattern set to 1. the value in the table, or alternatively 2. the
|
||||
string value, or 3. the pattern from the global defaults.<br/>
|
||||
<br/>
|
||||
Returns a logPatterns table.<br/>
|
||||
<br/>
|
||||
Example logging source info only on debug-level, and coloring error and fatal
|
||||
messages:
|
||||
<pre class="example">
|
||||
local patterns = logging.buildLogPatterns(
|
||||
{
|
||||
[logging.DEBUG] = "%date %level %message (%source)\n"
|
||||
[logging.ERROR] = "%date "..ansi_red.."%level %message"..ansi_reset.."\n"
|
||||
[logging.FATAL] = "%date "..ansi_red.."%level %message"..ansi_reset.."\n"
|
||||
}, "%date %level %message\n"
|
||||
)
|
||||
</pre>
|
||||
</dd>
|
||||
|
||||
<dt><strong>date_val = logging.date([format,[time]])</strong></dt>
|
||||
<dd>Compatible with standard Lua <code>os.date()</code> function, but supports second fractions.
|
||||
The placeholder in the format string is <code>"%q"</code>, or <code>"%1q"</code> to <code>"%6q"</code>,
|
||||
where the number 1-6 specifies the number of decimals. The default is 3, so <code>"%q"</code> is the same
|
||||
as <code>"%3q"</code>. The format will always have the specified length, padded with leading and trailing 0's
|
||||
where necessary.<br/>
|
||||
If the pattern is <code>"*t"</code>, then the returned table will have an extra field <code>"secf"</code> that holds
|
||||
the fractional part.<br/>
|
||||
<br/>
|
||||
Example: <code>"%y-%m-%d %H:%M:%S.%6q"</code><br/>
|
||||
<br/>
|
||||
Note: if the "time" parameter is not provided, it will try and use the LuaSocket function <code>gettime()</code>
|
||||
to get the time. If unavailable, the fractional part will be set to 0.
|
||||
</dd>
|
||||
|
||||
<dt><strong>patts = logging.defaultLogPatterns([string | table])</strong></dt>
|
||||
<dd>Sets the default logPatterns (global!) if a parameter is given.
|
||||
If the parameter is a string then that string will be used as the pattern for
|
||||
all log-levels. If a table is given, then it must have all log-levels defined
|
||||
with a pattern string. See also <code>logging.buildLogPatterns</code>.<br/>
|
||||
<br/>
|
||||
The default is <code>"%date %level %message\n"</code> for all log-levels.<br/>
|
||||
<br/>
|
||||
Available placeholders in the pattern string are; <code>"%date"</code>, <code>"%level"</code>, <code>"%message"</code>,
|
||||
<code>"%file"</code>, <code>"%line"</code>, <code>"%function"</code> and <code>"%source"</code>. The <code>"%source"</code> placeholder evaluates
|
||||
to <code>"%file:%line in function'%function'"</code>.<br/>
|
||||
<br/>
|
||||
Returns the current defaultLogPatterns value.<br/>
|
||||
<br/>
|
||||
<em>NOTE:</em> since this is a global setting, libraries should never set it,
|
||||
only applications should.
|
||||
</dd>
|
||||
|
||||
<dt><strong>patt = logging.defaultTimestampPattern([string])</strong></dt>
|
||||
<dd>Sets the default timestampPattern (global!) if given.
|
||||
The default is <code>nil</code>, which results in a system specific date/time format.
|
||||
The pattern should be accepted by the function <code>logging.date</code> for formatting.<br/>
|
||||
<br/>
|
||||
Returns the current defaultTimestampPattern value.<br/>
|
||||
<br/>
|
||||
<em>NOTE:</em> since this is a global setting, libraries should never set it,
|
||||
only applications should.
|
||||
</dd>
|
||||
|
||||
<dt><strong>level = logging.defaultLevel([level constant])</strong></dt>
|
||||
<dd>Sets the default log-level (global!) if given. Each new logger object created
|
||||
will start with the log-level as specified by this value.
|
||||
The level parameter must be one of the log-level constants. The default is <code>logging.DEBUG</code>.<br/>
|
||||
<br/>
|
||||
Returns the current defaultLevel value.<br/>
|
||||
<br/>
|
||||
<em>NOTE:</em> since this is a global setting, libraries should never set it,
|
||||
only applications should.
|
||||
</dd>
|
||||
|
||||
<dt><strong>logger = logging.defaultLogger([logger object])</strong></dt>
|
||||
<dd>Sets the default logger object (global!) if given.
|
||||
The logger parameter must be a LuaLogging logger object. The default is to
|
||||
generate a new <code>console</code> logger (with "destination" set to "stderr")
|
||||
on the first call to get the default logger.<br/>
|
||||
<br/>
|
||||
Returns the current defaultLogger value.<br/>
|
||||
<br/>
|
||||
<em>NOTE:</em> since this is a global setting, libraries should never set it,
|
||||
only applications should. Libraries should get this logger and use it, assuming
|
||||
the application has set it.
|
||||
<pre class="example">
|
||||
-- Example: application setting the default logger
|
||||
local color = require("ansicolors") -- https://github.com/kikito/ansicolors.lua
|
||||
local ll = require("logging")
|
||||
require "logging.console"
|
||||
ll.defaultLogger(ll.console {
|
||||
destination = "stderr",
|
||||
timestampPattern = "!%y-%m-%dT%H:%M:%S.%qZ", -- ISO 8601 in UTC
|
||||
logPatterns = {
|
||||
[ll.DEBUG] = color("%{white}%date%{cyan} %level %message (%source)\n"),
|
||||
[ll.INFO] = color("%{white}%date%{white} %level %message\n"),
|
||||
[ll.WARN] = color("%{white}%date%{yellow} %level %message\n"),
|
||||
[ll.ERROR] = color("%{white}%date%{red bright} %level %message %{cyan}(%source)\n"),
|
||||
[ll.FATAL] = color("%{white}%date%{magenta bright} %level %message %{cyan}(%source)\n"),
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
-- Example: library using default if available (fallback to nop)
|
||||
local log do
|
||||
local ll = package.loaded.logging
|
||||
if ll and type(ll) == "table" and ll.defaultLogger and
|
||||
tostring(ll._VERSION):find("LuaLogging") then
|
||||
-- default LuaLogging logger is available
|
||||
log = ll.defaultLogger()
|
||||
else
|
||||
-- just use a stub logger with only no-op functions
|
||||
local nop = function() end
|
||||
log = setmetatable({}, {
|
||||
__index = function(self, key) self[key] = nop return nop end
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
log:debug("starting my library")
|
||||
</pre>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
|
||||
<h2><a name="environment"></a>Environment variables</h2>
|
||||
|
||||
<p>The submodule <code>logging.envconfig</code> allows to configure the default
|
||||
logger via environment variables. This is done based on a "prefix" for the environment
|
||||
variables (with default value "LL").
|
||||
The variables are the logger options names with the prefix in all-caps separated by "_".
|
||||
So if a logger takes an option "<code>opts.logLevel</code>", then it can be configured
|
||||
using environment variable <code>LL_LOGLEVEL=warn</code>.</p>
|
||||
|
||||
<p>The type of logger can be set using environment variable <code>LL_LOGGER=console</code>
|
||||
(assuming the default prefix "LL").</p>
|
||||
|
||||
<p>The defaults are "LL" for the prefix, and a console logger to "stderr".</p>
|
||||
|
||||
<p>The exposed functions:</p>
|
||||
<dl class="reference">
|
||||
<dt><strong>envconfig.set_default_settings(prefix)</strong></dt>
|
||||
<dd>Sets the default prefix and loads the configuration. Returns <code>true</code> on
|
||||
success, <code>nil, "already set a default"</code> if it was called before. Will
|
||||
throw an error if something during the configuration fails (bad user input in environment
|
||||
variables for example).<br/>
|
||||
This method should be called by applications at startup, to set the default prefix.
|
||||
</dd>
|
||||
|
||||
<dt><strong>name, opts = envconfig.get_default_settings()</strong></dt>
|
||||
<dd>returns the appender name (eg. "file", "console", etc), and the options table for
|
||||
configuring the appender. The table has a metatable that will dynamically lookup
|
||||
fields in environment variables, this ensures that any option an appender checks
|
||||
will be read and returned.
|
||||
Boolean and number values will be converted to their respective types (case insensitive).<br/>
|
||||
<br/>
|
||||
The common <code>logPatterns</code> field is a special case where each level can be
|
||||
configured by appending the level with an "_". See example below:
|
||||
<pre class="example">
|
||||
# set these environment variables
|
||||
export MYAPP_LOGGER="console"
|
||||
export MYAPP_LOGLEVEL="info"
|
||||
export MYAPP_LOGPATTERN = "%message"
|
||||
export MYAPP_LOGPATTERNS_DEBUG = "%message %source"
|
||||
export MYAPP_LOGPATTERNS_FATAL = "Oh my!! %message"
|
||||
|
||||
-- Lua code (see set_default_logger for a shorter version)
|
||||
local logging = require "logging"
|
||||
local logenv = require "logging.envconfig"
|
||||
assert(logenv.set_default_settings("MYAPP"))
|
||||
local logger_name, logger_opts = logenv.get_default_settings()
|
||||
local logger = assert(require("logging."..logger_name)(logger_opts))
|
||||
logging.setdefaultLogger(logger)
|
||||
|
||||
logger:info("configured via environment!")
|
||||
</pre>
|
||||
</dd>
|
||||
|
||||
<dt><strong>logger = envconfig.set_default_logger(prefix)</strong></dt>
|
||||
<dd>Sets (and returns) the default logger from the environment.
|
||||
<pre class="example">
|
||||
# set these environment variables
|
||||
export MYAPP_LOGGER="console"
|
||||
export MYAPP_LOGLEVEL="info"
|
||||
export MYAPP_LOGPATTERN = "%message"
|
||||
export MYAPP_LOGPATTERNS_DEBUG = "%message %source"
|
||||
export MYAPP_LOGPATTERNS_FATAL = "Oh my!! %message"
|
||||
|
||||
-- Lua code
|
||||
local logenv = require "logging.envconfig"
|
||||
local logger = assert(logenv.set_default_logger("MYAPP"))
|
||||
|
||||
logger:info("configured via environment!")
|
||||
</pre>
|
||||
</dd>
|
||||
|
||||
|
||||
</dl>
|
||||
|
||||
|
||||
<h2><a name="logger"></a>Logger objects</h2>
|
||||
|
||||
<p>Logger objects are created by loading the 'appender' module, and calling on it. For example:</p>
|
||||
<pre class="example">
|
||||
local logger = require("logging.console") {
|
||||
-- options go here (see appenders for options)
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>A logger object offers the following methods that write log messages.</p>
|
||||
|
||||
<p>For each of the methods below, the parameter <code>message</code> may be any lua value,
|
||||
not only strings. When necessary <code>message</code> is converted to a string.</p>
|
||||
|
||||
<p>The parameter <code>level</code> can be one of the variables enumerated below.
|
||||
The values are presented in descending criticality, so if the minimum level is
|
||||
defined as <code>logger.WARN</code> then <code>logger.INFO</code> and
|
||||
<code>logger.DEBUG</code> level messages are not logged.
|
||||
The default set level at startup is <code>logger.DEBUG</code>.</p>
|
||||
|
||||
<h3>Constants</h3>
|
||||
|
||||
<dl class="reference">
|
||||
<dt><strong>logger.DEBUG</strong></dt>
|
||||
<dd>The <em>DEBUG</em> level designates fine-grained informational events that
|
||||
are most useful to debug an application.</dd>
|
||||
|
||||
<dt><strong>logger.INFO</strong></dt>
|
||||
<dd>The <em>INFO</em> level designates informational messages that highlight the
|
||||
progress of the application at coarse-grained level.</dd>
|
||||
|
||||
<dt><strong>logger.WARN</strong></dt>
|
||||
<dd>The <em>WARN</em> level designates potentially harmful situations.</dd>
|
||||
|
||||
<dt><strong>logger.ERROR</strong></dt>
|
||||
<dd>The <em>ERROR</em> level designates error events that might still allow the
|
||||
application to continue running.</dd>
|
||||
|
||||
<dt><strong>logger.FATAL</strong></dt>
|
||||
<dd>The <em>FATAL</em> level designates very severe error events that would
|
||||
presumably lead the application to abort.</dd>
|
||||
|
||||
<dt><strong>logger.OFF</strong></dt>
|
||||
<dd>The <em>OFF</em> level will stop all log messages.</dd>
|
||||
</dl>
|
||||
|
||||
<h3>Methods</h3>
|
||||
|
||||
<dl class="reference">
|
||||
<dt><strong>logger:log (level, [message]|[table]|[format, ...]|[function, ...])</strong></dt>
|
||||
<dd>Logs a message with the specified level.</dd>
|
||||
|
||||
<dt><strong>logger:setLevel (level)</strong></dt>
|
||||
<dd>This method sets a minimum level for messages to be logged.</dd>
|
||||
|
||||
<dt><strong>logger:getPrint (level)</strong></dt>
|
||||
<dd>This method returns a print-like function that redirects all output to
|
||||
the logger instead of the console. The <code>level</code> parameter specifies
|
||||
the log-level of the output.</dd>
|
||||
</dl>
|
||||
|
||||
<p>The following set of methods is dynamically generated from the log-levels.</p>
|
||||
|
||||
<dl class="reference">
|
||||
|
||||
<dt><strong>logger:debug ([message]|[table]|[format, ...]|[function, ...])</strong></dt>
|
||||
<dd>Logs a message with DEBUG level.</dd>
|
||||
|
||||
<dt><strong>logger:info ([message]|[table]|[format, ...]|[function, ...])</strong></dt>
|
||||
<dd>Logs a message with INFO level.</dd>
|
||||
|
||||
<dt><strong>logger:warn ([message]|[table]|[format, ...]|[function, ...])</strong></dt>
|
||||
<dd>Logs a message with WARN level.</dd>
|
||||
|
||||
<dt><strong>logger:error ([message]|[table]|[format, ...]|[function, ...])</strong></dt>
|
||||
<dd>Logs a message with ERROR level.</dd>
|
||||
|
||||
<dt><strong>logger:fatal ([message]|[table]|[format, ...]|[function, ...])</strong></dt>
|
||||
<dd>Logs a message with FATAL level.</dd>
|
||||
</dl>
|
||||
|
||||
<h2><a name="examples"></a>Examples</h2>
|
||||
|
||||
<p>The example below creates a logger that prints the level and message
|
||||
to the standard output (or whatever the print function does).</p>
|
||||
|
||||
<pre class="example">
|
||||
local Logging = require "logging"
|
||||
|
||||
local appender = function(self, level, message)
|
||||
print(level, message)
|
||||
return true
|
||||
end
|
||||
|
||||
local logger = Logging.new(appender)
|
||||
|
||||
logger:setLevel(logger.WARN)
|
||||
logger:log(logger.INFO, "sending email")
|
||||
|
||||
logger:info("trying to contact server")
|
||||
logger:warn("server did not respond yet")
|
||||
logger:error("server unreachable")
|
||||
|
||||
-- dump a table in a log message
|
||||
local tab = { a = 1, b = 2 }
|
||||
logger:debug(tab)
|
||||
|
||||
-- use string.format() style formatting
|
||||
logger:info("val1='%s', val2=%d", "string value", 1234)
|
||||
|
||||
-- complex log formatting.
|
||||
local function log_callback(val1, val2)
|
||||
-- Do some complex pre-processing of parameters, maybe dump a table to a string.
|
||||
return string.format("val1='%s', val2=%d", val1, val2)
|
||||
end
|
||||
|
||||
-- function 'log_callback' will only be called if the current log level is "DEBUG"
|
||||
logger:debug(log_callback, "string value", 1234)
|
||||
|
||||
-- create a print that redirects to the logger at level "INFO"
|
||||
logger:setLevel (logger.INFO)
|
||||
local print = logger:getPrint(logger.INFO)
|
||||
print "hello\nthere!"
|
||||
</pre>
|
||||
|
||||
<p>Upon execution of the above example the following lines will
|
||||
show in the standard output. Notice that some of the <em>INFO</em> log requests
|
||||
are not handled because the minimum level is set to <em>WARN</em>.</p>
|
||||
|
||||
<pre class="example">
|
||||
WARN server did not responded yet
|
||||
ERROR server unreachable
|
||||
INFO hello
|
||||
INFO there!
|
||||
</pre>
|
||||
|
||||
<a name="appenders"></a>
|
||||
|
||||
<h2>Appenders</h2>
|
||||
|
||||
The following appenders are included in the standard distribution.
|
||||
|
||||
<ul>
|
||||
<li><a href="console.html">Console</a></li>
|
||||
<li><a href="file.html">File</a></li>
|
||||
<li><a href="rolling_file.html">Rolling File</a></li>
|
||||
<li><a href="sql.html">SQL</a></li>
|
||||
<li><a href="socket.html">Socket</a></li>
|
||||
<li><a href="rsyslog.html">Rsyslog</a></li>
|
||||
<li><a href="email.html">Email</a></li>
|
||||
<li><a href="nginx.html">Nginx/OpenResty</a></li>
|
||||
</ul>
|
||||
|
||||
<h2>Upgrading from 1.0.0</h2>
|
||||
|
||||
<p>Upgrading from LuaLogging 1.0.0 is very easy. The
|
||||
<code>logger</code> object is fully compatible. You just need to
|
||||
change the code that creates the object.</p>
|
||||
|
||||
<p>The <code>logger</code> constructor from 1.0.0 received a single
|
||||
argument which was a filename. To upgrade to 1.1.0 you should
|
||||
create a <code>logging.file</code> object instead, passing the
|
||||
filename as argument. As simple as this.</p>
|
||||
|
||||
</div> <!-- id="content" -->
|
||||
|
||||
</div> <!-- id="main" -->
|
||||
|
||||
<div id="about">
|
||||
<p><a href="https://validator.w3.org/check?uri=referer">
|
||||
<img src="https://www.w3.org/Icons/valid-xhtml10" alt="XHTML 1.0 válido!" height="31" width="88" /></a></p>
|
||||
</div> <!-- id="about" -->
|
||||
|
||||
</div> <!-- id="container" -->
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,98 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"https://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="https://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<title>LuaLogging: A simple API to use logging features in Lua</title>
|
||||
<link rel="stylesheet" href="doc.css" type="text/css"/>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="container">
|
||||
|
||||
<div id="product">
|
||||
<div id="product_logo">
|
||||
<img alt="LuaLogging logo" src="images/lualogging-128.png"/>
|
||||
</div>
|
||||
<div id="product_name"><big><strong>LuaLogging</strong></big></div>
|
||||
<div id="product_description">A simple API to use logging features in Lua.</div>
|
||||
</div> <!-- id="product" -->
|
||||
|
||||
<div id="main">
|
||||
|
||||
<div id="navigation">
|
||||
<h1>LuaLogging</h1>
|
||||
<ul>
|
||||
<li><a href="index.html">Home</a></li>
|
||||
<li><a href="manual.html">Manual</a>
|
||||
<ul>
|
||||
<li><a href="manual.html#installation">Installation</a></li>
|
||||
<li><a href="manual.html#logger">Logger objects</a></li>
|
||||
<li><a href="manual.html#examples">Examples</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="manual.html#appenders">Appenders</a>
|
||||
<ul>
|
||||
<li><a href="console.html">Console</a></li>
|
||||
<li><a href="file.html">File</a></li>
|
||||
<li><a href="rolling_file.html">Rolling File</a></li>
|
||||
<li><a href="sql.html">SQL</a></li>
|
||||
<li><a href="socket.html">Socket</a></li>
|
||||
<li><a href="rsyslog.html">Rsyslog</a></li>
|
||||
<li><a href="email.html">Email</a></li>
|
||||
<li><strong>Nginx</strong></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="https://github.com/lunarmodules/lualogging">Project</a></li>
|
||||
<li><a href="license.html">License</a></li>
|
||||
</ul>
|
||||
</div> <!-- id="navigation" -->
|
||||
|
||||
<div id="content">
|
||||
|
||||
<h2>Nginx/Openresty appender</h2>
|
||||
|
||||
<p>This appender has no configuration options, and simply forwards whatever is
|
||||
being logged to the configured Nginx log. LuaLogging log-levels will be converted
|
||||
to the equivalent Nginx ones, and initial log-level will be set to match the
|
||||
Nginx system level.</p>
|
||||
<p>It makes sense to configure this logger and set it as the default logger on
|
||||
Nginx/OpenResty startup. Any libraries will then be able to just grab the
|
||||
defaultLogger from <code>logging.defaultLogger()</code> and won't need any
|
||||
modifications to work with Nginx/OpenResty.</p>
|
||||
|
||||
<h2>Examples</h2>
|
||||
|
||||
<pre class="example">
|
||||
require("logging.nginx")
|
||||
local logging = require("logging")
|
||||
|
||||
local logger = logging.nginx()
|
||||
logging.defaultLogger(logger)
|
||||
|
||||
logger:info("logging.nginx test")
|
||||
logger:debug("debugging...")
|
||||
logger:error("error!")
|
||||
</pre>
|
||||
|
||||
<p> </p>
|
||||
<p> </p>
|
||||
<p> </p>
|
||||
<p> </p>
|
||||
<p> </p>
|
||||
<p> </p>
|
||||
<p> </p>
|
||||
|
||||
</div> <!-- id="content" -->
|
||||
|
||||
</div> <!-- id="main" -->
|
||||
|
||||
<div id="about">
|
||||
<p><a href="https://validator.w3.org/check?uri=referer">
|
||||
<img src="https://www.w3.org/Icons/valid-xhtml10" alt="XHTML 1.0 válido!" height="31" width="88" /></a></p>
|
||||
</div> <!-- id="about" -->
|
||||
|
||||
</div> <!-- id="container" -->
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,153 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"https://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="https://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<title>LuaLogging: A simple API to use logging features in Lua</title>
|
||||
<link rel="stylesheet" href="doc.css" type="text/css"/>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="container">
|
||||
|
||||
<div id="product">
|
||||
<div id="product_logo">
|
||||
<img alt="LuaLogging logo" src="images/lualogging-128.png"/>
|
||||
</div>
|
||||
<div id="product_name"><big><strong>LuaLogging</strong></big></div>
|
||||
<div id="product_description">A simple API to use logging features in Lua.</div>
|
||||
</div> <!-- id="product" -->
|
||||
|
||||
<div id="main">
|
||||
|
||||
<div id="navigation">
|
||||
<h1>LuaLogging</h1>
|
||||
<ul>
|
||||
<li><a href="index.html">Home</a></li>
|
||||
<li><a href="manual.html">Manual</a>
|
||||
<ul>
|
||||
<li><a href="manual.html#installation">Installation</a></li>
|
||||
<li><a href="manual.html#logger">Logger objects</a></li>
|
||||
<li><a href="manual.html#examples">Examples</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="manual.html#appenders">Appenders</a>
|
||||
<ul>
|
||||
<li><a href="console.html">Console</a></li>
|
||||
<li><a href="file.html">File</a></li>
|
||||
<li><strong>Rolling File</strong></li>
|
||||
<li><a href="sql.html">SQL</a></li>
|
||||
<li><a href="socket.html">Socket</a></li>
|
||||
<li><a href="rsyslog.html">Rsyslog</a></li>
|
||||
<li><a href="email.html">Email</a></li>
|
||||
<li><a href="nginx.html">Nginx</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="https://github.com/lunarmodules/lualogging">Project</a></li>
|
||||
<li><a href="license.html">License</a></li>
|
||||
</ul>
|
||||
</div> <!-- id="navigation" -->
|
||||
|
||||
<div id="content">
|
||||
|
||||
<h2>Rolling File appender</h2>
|
||||
|
||||
<p>The rolling file appender can be used to write log messages to a file. It
|
||||
uses Lua I/O routines to do its job. The rolling file appender rolls over the logfile
|
||||
once it has reached a certain size limit. It also mantains a maximum number of log files.</p>
|
||||
|
||||
<pre class="example">
|
||||
function logging.rolling_file {
|
||||
[filename = <i>string</i>,]
|
||||
maxFileSize = <i>number</i>,
|
||||
[maxBackupIndex = <i>number</i>,]
|
||||
|
||||
[logPattern = <i>string</i>,]
|
||||
[logPatterns = {
|
||||
[logging.DEBUG = <i>string</i>,]
|
||||
[logging.INFO = <i>string</i>,]
|
||||
[logging.WARN = <i>string</i>,]
|
||||
[logging.ERROR = <i>string</i>,]
|
||||
[logging.FATAL = <i>string</i>,]
|
||||
},]
|
||||
[timestampPattern = <i>string</i>,]
|
||||
[logLevel = <i>log-level-constant</i>,]
|
||||
}
|
||||
</pre>
|
||||
|
||||
<ul>
|
||||
<li><code>filename</code>:<br />
|
||||
The name of the file to be written to.<br />
|
||||
If the file cannot be opened for appending the logging request
|
||||
returns nil and an error message.<br />
|
||||
The default value is <code>"lualogging.log"</code>.</li>
|
||||
|
||||
<li><code>maxFileSize</code>:<br />
|
||||
The max size of the file in bytes. Every time the file reaches this size
|
||||
it will rollover, generating a new clean log file and storing the old log
|
||||
on a filename.n, where n goes from 1 to the configured maxBackupIndex.<br />
|
||||
The more recent backup is the one with the lowest n on its filename.<br />
|
||||
Eg. test.log.1 (most recent backup) <br />
|
||||
test.log.2 (least recent backup)
|
||||
</li>
|
||||
|
||||
<li><code>maxBackupIndex</code>:<br />
|
||||
The number of backup files that will be generated.
|
||||
The default value is <code>1</code>.</li>
|
||||
|
||||
<li><code>logPatterns</code>:<br />
|
||||
A table with logPattern strings indexed by the log-levels.
|
||||
A logPattern specifies how the message is written.<br />
|
||||
If this parameter is omitted, a patterns table will be created with the
|
||||
parameter <code>logPattern</code> as the default value for each log-level.
|
||||
If <code>logPattern</code> also is omitted then each level will fall back to
|
||||
the current default setting, see <code>logging.defaultLogPatterns</code>.
|
||||
</li>
|
||||
|
||||
<li><code>logPattern</code>:<br />
|
||||
This value will be used as the default value for each log-level that was
|
||||
omitted in <code>logPatterns</code>.
|
||||
</li>
|
||||
|
||||
<li><code>timestampPattern</code>:<br />
|
||||
This is an optional parameter that can be used to specify a date/time formatting
|
||||
in the log message.
|
||||
See <code>logging.date</code> for the format.
|
||||
The default is taken from <code>logging.defaultTimestampPattern()</code>.</li>
|
||||
|
||||
<li><code>logLevel</code>:<br />
|
||||
The initial log-level to set for the created logger.</li>
|
||||
</ul>
|
||||
|
||||
<h2>Example</h2>
|
||||
|
||||
<pre class="example">
|
||||
require"logging.rolling_file"
|
||||
|
||||
local logger = logging.rolling_file {
|
||||
filename = "test.log",
|
||||
maxFileSize = 1024,
|
||||
maxBackupIndex = 5,
|
||||
}
|
||||
|
||||
logger:info("logging.rolling_file test")
|
||||
logger:debug("debugging...")
|
||||
logger:error("error!")
|
||||
</pre>
|
||||
|
||||
<p> </p>
|
||||
<p> </p>
|
||||
|
||||
</div> <!-- id="content" -->
|
||||
|
||||
</div> <!-- id="main" -->
|
||||
|
||||
<div id="about">
|
||||
<p><a href="https://validator.w3.org/check?uri=referer">
|
||||
<img src="https://www.w3.org/Icons/valid-xhtml10" alt="XHTML 1.0 válido!" height="31" width="88" /></a></p>
|
||||
</div> <!-- id="about" -->
|
||||
|
||||
</div> <!-- id="container" -->
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,239 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"https://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="https://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<title>LuaLogging: A simple API to use logging features in Lua</title>
|
||||
<link rel="stylesheet" href="doc.css" type="text/css"/>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="container">
|
||||
|
||||
<div id="product">
|
||||
<div id="product_logo">
|
||||
<img alt="LuaLogging logo" src="images/lualogging-128.png"/>
|
||||
</div>
|
||||
<div id="product_name"><big><strong>LuaLogging</strong></big></div>
|
||||
<div id="product_description">A simple API to use logging features in Lua.</div>
|
||||
</div> <!-- id="product" -->
|
||||
|
||||
<div id="main">
|
||||
|
||||
<div id="navigation">
|
||||
<h1>LuaLogging</h1>
|
||||
<ul>
|
||||
<li><a href="index.html">Home</a></li>
|
||||
<li><a href="manual.html">Manual</a>
|
||||
<ul>
|
||||
<li><a href="manual.html#installation">Installation</a></li>
|
||||
<li><a href="manual.html#logger">Logger objects</a></li>
|
||||
<li><a href="manual.html#examples">Examples</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="manual.html#appenders">Appenders</a>
|
||||
<ul>
|
||||
<li><a href="console.html">Console</a></li>
|
||||
<li><a href="file.html">File</a></li>
|
||||
<li><a href="rolling_file.html">Rolling File</a></li>
|
||||
<li><a href="sql.html">SQL</a></li>
|
||||
<li><a href="socket.html">Socket</a></li>
|
||||
<li><strong>Rsyslog</strong></li>
|
||||
<li><a href="email.html">Email</a></li>
|
||||
<li><a href="nginx.html">Nginx</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="https://github.com/lunarmodules/lualogging">Project</a></li>
|
||||
<li><a href="license.html">License</a></li>
|
||||
</ul>
|
||||
</div> <!-- id="navigation" -->
|
||||
|
||||
<div id="content">
|
||||
|
||||
<h2>Remote syslog appender</h2>
|
||||
|
||||
<p>This appender can be used to send syslog formatted log requests to a remote syslog server.
|
||||
This appender relies on <a href="https://github.com/lunarmodules/luasocket">LuaSocket</a>
|
||||
to do its job. Optionally <a href="https://github.com/lunarmodules/copas">Copas</a> can be
|
||||
used for async sending of log messages over TCP.<br /></p>
|
||||
|
||||
<p>If you want to log to the local syslog daemon, then please use
|
||||
<a href="https://github.com/lunarmodules/luasyslog">luasyslog</a>.</p>
|
||||
|
||||
<p>The LuaLogging log-levels will be mapped to the syslog levels by their name, where
|
||||
<code>logging.FATAL</code> maps to syslog <code>ALERT</code>. Since LuaLogging only has 5
|
||||
levels, the syslog levels <code>EMERG</code>, <code>CRIT</code>, and <code>NOTICE</code>
|
||||
remain unused.</p>
|
||||
|
||||
<pre class="example">
|
||||
function logging.rsyslog {
|
||||
hostname = <i>string</i>,
|
||||
[port = <i>number</i>,]
|
||||
[protocol = <i>"udp"</i> | <i>"tcp"</i>,]
|
||||
[rfc = <i>"rfc5424"</i> | <i>"rfc3164"</i>,]
|
||||
[maxsize = <i>number</i>,]
|
||||
[facility = <i>facility-constant</i>,]
|
||||
[ident = <i>string</i>,]
|
||||
[procid = <i>string</i>,]
|
||||
[msgid = <i>string</i>,]
|
||||
|
||||
[logPattern = <i>string</i>,]
|
||||
[logPatterns = {
|
||||
[logging.DEBUG = <i>string</i>,]
|
||||
[logging.INFO = <i>string</i>,]
|
||||
[logging.WARN = <i>string</i>,]
|
||||
[logging.ERROR = <i>string</i>,]
|
||||
[logging.FATAL = <i>string</i>,]
|
||||
},]
|
||||
[logLevel = <i>log-level-constant</i>,]
|
||||
}
|
||||
</pre>
|
||||
|
||||
<ul>
|
||||
<li><code>hostname</code>:<br />
|
||||
Hostname can be an IP address or a host name of the server where the log
|
||||
message will be sent.
|
||||
</li>
|
||||
|
||||
<li><code>port</code>:<br />
|
||||
The port must be an integer number in the range [1..64K). The default is
|
||||
<code>514</code>.
|
||||
</li>
|
||||
|
||||
<li><code>protocol</code>:<br />
|
||||
The network protocol to use, either <code>"udp"</code> or <code>"tcp"</code>.
|
||||
The default is <code>"tcp"</code>.
|
||||
<br/><br/>
|
||||
Note: TCP sending is a blocking operation. For non-blocking use
|
||||
<a href="https://github.com/lunarmodules/copas">Copas</a>
|
||||
is supported, see the example below.
|
||||
</li>
|
||||
|
||||
<li><code>rfc</code>:<br />
|
||||
The message format. 2 options:
|
||||
<ul>
|
||||
<li>for the old BSD style use <code>"rfc3164"</code> (the default)</li>
|
||||
<li>for the IETF standard use <code>"rfc5424"</code>.</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li><code>maxsize</code>:<br />
|
||||
The maximum message size. Longer messages will be truncated. The minimum value is 480.
|
||||
The defaults are 1024 for <code>"rfc3164"</code>, and 2048 for <code>"rfc5424"</code>.
|
||||
</li>
|
||||
|
||||
<li><code>facility</code>:<br />
|
||||
The syslog facility to use, use one of the constants. The default value
|
||||
is the "user" facility.
|
||||
<pre class="example">
|
||||
rsyslog.FACILITY_KERN
|
||||
rsyslog.FACILITY_USER
|
||||
rsyslog.FACILITY_MAIL
|
||||
rsyslog.FACILITY_DAEMON
|
||||
rsyslog.FACILITY_AUTH
|
||||
rsyslog.FACILITY_SYSLOG
|
||||
rsyslog.FACILITY_LPR
|
||||
rsyslog.FACILITY_NEWS
|
||||
rsyslog.FACILITY_UUCP
|
||||
rsyslog.FACILITY_CRON
|
||||
rsyslog.FACILITY_AUTHPRIV
|
||||
rsyslog.FACILITY_FTP
|
||||
rsyslog.FACILITY_NTP
|
||||
rsyslog.FACILITY_SECURITY
|
||||
rsyslog.FACILITY_CONSOLE
|
||||
rsyslog.FACILITY_NETINFO
|
||||
rsyslog.FACILITY_REMOTEAUTH
|
||||
rsyslog.FACILITY_INSTALL
|
||||
rsyslog.FACILITY_RAS
|
||||
rsyslog.FACILITY_LOCAL0
|
||||
rsyslog.FACILITY_LOCAL1
|
||||
rsyslog.FACILITY_LOCAL2
|
||||
rsyslog.FACILITY_LOCAL3
|
||||
rsyslog.FACILITY_LOCAL4
|
||||
rsyslog.FACILITY_LOCAL5
|
||||
rsyslog.FACILITY_LOCAL6
|
||||
rsyslog.FACILITY_LOCAL7
|
||||
</pre>
|
||||
</li>
|
||||
|
||||
<li><code>ident</code>:<br />
|
||||
The value for the APP-NAME field (rfc5424, called TAG field in rfc3164).
|
||||
Default value is <code>"lua"</code>.
|
||||
</li>
|
||||
|
||||
<li><code>procid</code>:<br />
|
||||
The process id value (only applicable for rfc5424 format).
|
||||
Default value is <code>"-"</code> (absent).
|
||||
</li>
|
||||
|
||||
<li><code>msgid</code>:<br />
|
||||
The message id value (only applicable for rfc5424 format).
|
||||
Default value is <code>"-"</code> (absent).
|
||||
</li>
|
||||
|
||||
<li><code>logPattern</code>:<br />
|
||||
This value will be used as the default value for each log-level that was
|
||||
omitted in <code>logPatterns</code>, this defaults to <code>"%message"</code>.
|
||||
The default pattern deviates from standard LuaLogging defaults since those
|
||||
do not make sense for syslog.
|
||||
</li>
|
||||
|
||||
<li><code>logPatterns</code>:<br />
|
||||
A table with logPattern strings indexed by the log-levels.
|
||||
A logPattern specifies how the message is written.<br />
|
||||
If this parameter is omitted, a patterns table will be created with the
|
||||
parameter <code>logPattern</code> as the default value for each log-level.
|
||||
</li>
|
||||
|
||||
<li><code>logLevel</code>:<br />
|
||||
The initial log-level to set for the created logger.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2>Example</h2>
|
||||
|
||||
<pre class="example">
|
||||
local rsyslog = require "logging.rsyslog"
|
||||
|
||||
rsyslog.copas() -- switch to using non-blocking Copas sockets
|
||||
|
||||
local logger = rsyslog {
|
||||
hostname = "syslog.mycompany.com",
|
||||
port = 514,
|
||||
protocol = "tcp",
|
||||
rfc = "rfc5424",
|
||||
maxsize = 8000,
|
||||
facility = rsyslog.FACILITY_LOCAL2,
|
||||
ident = "my_lua_app",
|
||||
procid = "socket_mod",
|
||||
logPattern = "%message %source",
|
||||
}
|
||||
|
||||
copas.loop(function()
|
||||
logger:info("logging.rsyslog test")
|
||||
logger:debug("debugging...")
|
||||
logger:error("error!")
|
||||
|
||||
-- destroy to ensure threads are shutdown (only for Copas)
|
||||
logger:destroy()
|
||||
end)
|
||||
</pre>
|
||||
|
||||
<p> </p>
|
||||
<p> </p>
|
||||
<p> </p>
|
||||
<p> </p>
|
||||
|
||||
</div> <!-- id="content" -->
|
||||
|
||||
</div> <!-- id="main" -->
|
||||
|
||||
<div id="about">
|
||||
<p><a href="https://validator.w3.org/check?uri=referer">
|
||||
<img src="https://www.w3.org/Icons/valid-xhtml10" alt="XHTML 1.0 válido!" height="31" width="88" /></a></p>
|
||||
</div> <!-- id="about" -->
|
||||
|
||||
</div> <!-- id="container" -->
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,144 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"https://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="https://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<title>LuaLogging: A simple API to use logging features in Lua</title>
|
||||
<link rel="stylesheet" href="doc.css" type="text/css"/>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="container">
|
||||
|
||||
<div id="product">
|
||||
<div id="product_logo">
|
||||
<img alt="LuaLogging logo" src="images/lualogging-128.png"/>
|
||||
</div>
|
||||
<div id="product_name"><big><strong>LuaLogging</strong></big></div>
|
||||
<div id="product_description">A simple API to use logging features in Lua.</div>
|
||||
</div> <!-- id="product" -->
|
||||
|
||||
<div id="main">
|
||||
|
||||
<div id="navigation">
|
||||
<h1>LuaLogging</h1>
|
||||
<ul>
|
||||
<li><a href="index.html">Home</a></li>
|
||||
<li><a href="manual.html">Manual</a>
|
||||
<ul>
|
||||
<li><a href="manual.html#installation">Installation</a></li>
|
||||
<li><a href="manual.html#logger">Logger objects</a></li>
|
||||
<li><a href="manual.html#examples">Examples</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="manual.html#appenders">Appenders</a>
|
||||
<ul>
|
||||
<li><a href="console.html">Console</a></li>
|
||||
<li><a href="file.html">File</a></li>
|
||||
<li><a href="rolling_file.html">Rolling File</a></li>
|
||||
<li><a href="sql.html">SQL</a></li>
|
||||
<li><strong>Socket</strong></li>
|
||||
<li><a href="rsyslog.html">Rsyslog</a></li>
|
||||
<li><a href="email.html">Email</a></li>
|
||||
<li><a href="nginx.html">Nginx</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="https://github.com/lunarmodules/lualogging">Project</a></li>
|
||||
<li><a href="license.html">License</a></li>
|
||||
</ul>
|
||||
</div> <!-- id="navigation" -->
|
||||
|
||||
<div id="content">
|
||||
|
||||
<h2>Socket appender</h2>
|
||||
|
||||
This appender can be used to send log requests through a socket.
|
||||
Socket appender relies on <a href=
|
||||
"https://www.tecgraf.puc-rio.br/luasocket">LuaSocket</a> to do its
|
||||
job.<br />
|
||||
Upon each log request a connection is opened, the message is sent
|
||||
and the connection is closed.
|
||||
|
||||
<pre class="example">
|
||||
function logging.socket {
|
||||
hostname = <i>string</i>,
|
||||
port = <i>number</i>,
|
||||
|
||||
[logPattern = <i>string</i>,]
|
||||
[logPatterns = {
|
||||
[logging.DEBUG = <i>string</i>,]
|
||||
[logging.INFO = <i>string</i>,]
|
||||
[logging.WARN = <i>string</i>,]
|
||||
[logging.ERROR = <i>string</i>,]
|
||||
[logging.FATAL = <i>string</i>,]
|
||||
},]
|
||||
[timestampPattern = <i>string</i>,]
|
||||
[logLevel = <i>log-level-constant</i>,]
|
||||
}
|
||||
</pre>
|
||||
|
||||
<ul>
|
||||
<li><code>hostname</code>:<br />
|
||||
Hostname can be an IP address or a host name of the server where the log
|
||||
message will be sent.</li>
|
||||
|
||||
<li><code>port</code>:<br />
|
||||
The port must be an integer number in the range [1..64K).</li>
|
||||
|
||||
<li><code>logPatterns</code>:<br />
|
||||
A table with logPattern strings indexed by the log-levels.
|
||||
A logPattern specifies how the message is written.<br />
|
||||
If this parameter is omitted, a patterns table will be created with the
|
||||
parameter <code>logPattern</code> as the default value for each log-level.
|
||||
If <code>logPattern</code> also is omitted then each level will fall back to
|
||||
the current default setting, see <code>logging.defaultLogPatterns</code>.
|
||||
</li>
|
||||
|
||||
<li><code>logPattern</code>:<br />
|
||||
This value will be used as the default value for each log-level that was
|
||||
omitted in <code>logPatterns</code>.
|
||||
</li>
|
||||
|
||||
<li><code>timestampPattern</code>:<br />
|
||||
This is an optional parameter that can be used to specify a date/time formatting
|
||||
in the log message.
|
||||
See <code>logging.date</code> for the format.
|
||||
The default is taken from <code>logging.defaultTimestampPattern()</code>.</li>
|
||||
|
||||
<li><code>logLevel</code>:<br />
|
||||
The initial log-level to set for the created logger.</li>
|
||||
</ul>
|
||||
|
||||
<h2>Example</h2>
|
||||
|
||||
<pre class="example">
|
||||
require"logging.socket"
|
||||
|
||||
local logger = logging.socket {
|
||||
hostname = "localhost",
|
||||
port = 5000,
|
||||
}
|
||||
|
||||
logger:info("logging.socket test")
|
||||
logger:debug("debugging...")
|
||||
logger:error("error!")
|
||||
</pre>
|
||||
|
||||
<p> </p>
|
||||
<p> </p>
|
||||
<p> </p>
|
||||
<p> </p>
|
||||
|
||||
</div> <!-- id="content" -->
|
||||
|
||||
</div> <!-- id="main" -->
|
||||
|
||||
<div id="about">
|
||||
<p><a href="https://validator.w3.org/check?uri=referer">
|
||||
<img src="https://www.w3.org/Icons/valid-xhtml10" alt="XHTML 1.0 válido!" height="31" width="88" /></a></p>
|
||||
</div> <!-- id="about" -->
|
||||
|
||||
</div> <!-- id="container" -->
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,139 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"https://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="https://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<title>LuaLogging: A simple API to use logging features in Lua</title>
|
||||
<link rel="stylesheet" href="doc.css" type="text/css"/>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="container">
|
||||
|
||||
<div id="product">
|
||||
<div id="product_logo">
|
||||
<img alt="LuaLogging logo" src="images/lualogging-128.png"/>
|
||||
</div>
|
||||
<div id="product_name"><big><strong>LuaLogging</strong></big></div>
|
||||
<div id="product_description">A simple API to use logging features in Lua.</div>
|
||||
</div> <!-- id="product" -->
|
||||
|
||||
<div id="main">
|
||||
|
||||
<div id="navigation">
|
||||
<h1>LuaLogging</h1>
|
||||
<ul>
|
||||
<li><a href="index.html">Home</a></li>
|
||||
<li><a href="manual.html">Manual</a>
|
||||
<ul>
|
||||
<li><a href="manual.html#installation">Installation</a></li>
|
||||
<li><a href="manual.html#logger">Logger objects</a></li>
|
||||
<li><a href="manual.html#examples">Examples</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="manual.html#appenders">Appenders</a>
|
||||
<ul>
|
||||
<li><a href="console.html">Console</a></li>
|
||||
<li><a href="file.html">File</a></li>
|
||||
<li><a href="rolling_file.html">Rolling File</a></li>
|
||||
<li><strong>SQL</strong></li>
|
||||
<li><a href="socket.html">Socket</a></li>
|
||||
<li><a href="rsyslog.html">Rsyslog</a></li>
|
||||
<li><a href="email.html">Email</a></li>
|
||||
<li><a href="nginx.html">Nginx</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="https://github.com/lunarmodules/lualogging">Project</a></li>
|
||||
<li><a href="license.html">License</a></li>
|
||||
</ul>
|
||||
</div> <!-- id="navigation" -->
|
||||
|
||||
<div id="content">
|
||||
|
||||
<h2>SQL appender</h2>
|
||||
|
||||
<p>The SQL appender can be used to write log messages to a SQL
|
||||
database table. It uses <a href="https://keplerproject.github.io/luasql/">LuaSQL</a>,
|
||||
therefore any database supported by LuaSQL can be used.</p>
|
||||
|
||||
<pre class="example">
|
||||
function logging.sql{
|
||||
connectionfactory = <i>function</i>,
|
||||
[tablename = <i>string</i>,]
|
||||
[logdatefield = <i>string</i>,]
|
||||
[loglevelfield = <i>string</i>,]
|
||||
[logmessagefield = <i>string</i>,]
|
||||
[keepalive = <i>boolean</i>,]
|
||||
|
||||
[logLevel = <i>log-level-constant</i>,]
|
||||
}
|
||||
</pre>
|
||||
|
||||
<ul>
|
||||
<li><code>connectionfactory</code>:<br />
|
||||
This must be a function that creates a LuaSQL connection object.
|
||||
This function will be called everytime a connection needs to be
|
||||
created.</li>
|
||||
|
||||
<li><code>tablename</code>:<br />
|
||||
The name of the table to write the log requests. Default value is
|
||||
<code>"LogTable"</code>.</li>
|
||||
|
||||
<li><code>logdatefield</code>:<br />
|
||||
The name of the field to write the date of each log request.
|
||||
Default value is <code>"LogDate"</code>.</li>
|
||||
|
||||
<li><code>loglevelfield</code>:<br />
|
||||
The name of the field to write the level of each log request.
|
||||
Default value is <code>"LogLevel"</code>.</li>
|
||||
|
||||
<li><code>logmessagefield</code>:<br />
|
||||
The name of the field to write the message of each log request.
|
||||
Default value is <code>"LogMessage"</code>.</li>
|
||||
|
||||
<li><code>keepalive</code>:<br />
|
||||
In every log request a connection to the database is opened, the
|
||||
message is written, and the connection is closed.<br />
|
||||
If the user wants to keep the connection opened he can specify
|
||||
<code>keepalive = true</code>.</li>
|
||||
|
||||
<li><code>logLevel</code>:<br />
|
||||
The initial log-level to set for the created logger.</li>
|
||||
</ul>
|
||||
|
||||
<h2>Example</h2>
|
||||
|
||||
<pre class="example">
|
||||
require"logging.sql"
|
||||
require"luasql.jdbc"
|
||||
|
||||
local env, err = luasql.jdbc('com.mysql.jdbc.Driver')
|
||||
|
||||
local logger = logging.sql {
|
||||
connectionfactory = function()
|
||||
local con, err = env:connect('jdbc:mysql://localhost/test',
|
||||
'tcp', '123')
|
||||
assert(con, err)
|
||||
return con
|
||||
end,
|
||||
keepalive = true,
|
||||
}
|
||||
|
||||
logger:info("logging.sql test")
|
||||
logger:debug("debugging...")
|
||||
logger:error("error!")
|
||||
</pre>
|
||||
|
||||
</div> <!-- id="content" -->
|
||||
|
||||
</div> <!-- id="main" -->
|
||||
|
||||
<div id="about">
|
||||
<p><a href="https://validator.w3.org/check?uri=referer">
|
||||
<img src="https://www.w3.org/Icons/valid-xhtml10" alt="XHTML 1.0 válido!" height="31" width="88" /></a></p>
|
||||
</div> <!-- id="about" -->
|
||||
|
||||
</div> <!-- id="container" -->
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,47 @@
|
|||
local package_name = "lualogging"
|
||||
local package_version = "dev"
|
||||
local rockspec_revision = "1"
|
||||
local github_account_name = "lunarmodules"
|
||||
local github_repo_name = package_name
|
||||
|
||||
|
||||
package = package_name
|
||||
version = package_version.."-"..rockspec_revision
|
||||
source = {
|
||||
url = "git://github.com/"..github_account_name.."/"..github_repo_name..".git",
|
||||
branch = (package_version == "dev") and "master" or nil,
|
||||
tag = (package_version ~= "dev") and ("v"..package_version) or nil,
|
||||
}
|
||||
description = {
|
||||
summary = "A simple API to use logging features",
|
||||
detailed = [[
|
||||
LuaLogging provides a simple API to use logging features in Lua. Its design was
|
||||
based on log4j. LuaLogging currently supports, through the use of appenders,
|
||||
console, file, rolling file, email, socket and SQL outputs.
|
||||
]],
|
||||
homepage = "https://github.com/"..github_account_name.."/"..github_repo_name,
|
||||
license = "MIT/X11",
|
||||
}
|
||||
dependencies = {
|
||||
"luasocket"
|
||||
}
|
||||
build = {
|
||||
type = "none",
|
||||
install = {
|
||||
lua = {
|
||||
['logging'] = "src/logging.lua",
|
||||
['logging.console'] = "src/logging/console.lua",
|
||||
['logging.file'] = "src/logging/file.lua",
|
||||
['logging.rolling_file'] = "src/logging/rolling_file.lua",
|
||||
['logging.email'] = "src/logging/email.lua",
|
||||
['logging.sql'] = "src/logging/sql.lua",
|
||||
['logging.socket'] = "src/logging/socket.lua",
|
||||
['logging.nginx'] = "src/logging/nginx.lua",
|
||||
['logging.rsyslog'] = "src/logging/rsyslog.lua",
|
||||
['logging.envconfig'] = "src/logging/envconfig.lua",
|
||||
}
|
||||
},
|
||||
copy_directories = {
|
||||
"docs",
|
||||
},
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package = "lualogging"
|
||||
version = "1.2.0-2"
|
||||
source = {
|
||||
url = "git://github.com/lunarmodules/lualogging.git",
|
||||
branch = "v1.2.0",
|
||||
}
|
||||
description = {
|
||||
summary = "A simple API to use logging features",
|
||||
detailed = [[
|
||||
LuaLogging provides a simple API to use logging features in Lua. Its design was
|
||||
based on log4j. LuaLogging currently supports, through the use of appenders,
|
||||
console, file, rolling file, email, socket and SQL outputs.
|
||||
]],
|
||||
homepage = "https://github.com/lunarmodules/lualogging",
|
||||
license = "MIT/X11",
|
||||
}
|
||||
dependencies = {
|
||||
"luasocket"
|
||||
}
|
||||
build = {
|
||||
type = "none",
|
||||
install = {
|
||||
lua = {
|
||||
['logging'] = "src/logging.lua",
|
||||
['logging.console'] = "src/logging/console.lua",
|
||||
['logging.file'] = "src/logging/file.lua",
|
||||
['logging.rolling_file'] = "src/logging/rolling_file.lua",
|
||||
['logging.email'] = "src/logging/email.lua",
|
||||
['logging.sql'] = "src/logging/sql.lua",
|
||||
['logging.socket'] = "src/logging/socket.lua",
|
||||
}
|
||||
},
|
||||
copy_directories = {
|
||||
"doc/html",
|
||||
},
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package = "lualogging"
|
||||
version = "1.3.0-2"
|
||||
source = {
|
||||
url = "git://github.com/lunarmodules/lualogging.git",
|
||||
branch = "v1.3.0",
|
||||
}
|
||||
description = {
|
||||
summary = "A simple API to use logging features",
|
||||
detailed = [[
|
||||
LuaLogging provides a simple API to use logging features in Lua. Its design was
|
||||
based on log4j. LuaLogging currently supports, through the use of appenders,
|
||||
console, file, rolling file, email, socket and SQL outputs.
|
||||
]],
|
||||
homepage = "https://github.com/lunarmodules/lualogging",
|
||||
license = "MIT/X11",
|
||||
}
|
||||
dependencies = {
|
||||
"luasocket"
|
||||
}
|
||||
build = {
|
||||
type = "none",
|
||||
install = {
|
||||
lua = {
|
||||
['logging'] = "src/logging.lua",
|
||||
['logging.console'] = "src/logging/console.lua",
|
||||
['logging.file'] = "src/logging/file.lua",
|
||||
['logging.rolling_file'] = "src/logging/rolling_file.lua",
|
||||
['logging.email'] = "src/logging/email.lua",
|
||||
['logging.sql'] = "src/logging/sql.lua",
|
||||
['logging.socket'] = "src/logging/socket.lua",
|
||||
}
|
||||
},
|
||||
copy_directories = {
|
||||
"doc/html",
|
||||
},
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package = "lualogging"
|
||||
version = "1.4.0-1"
|
||||
source = {
|
||||
url = "git://github.com/lunarmodules/lualogging.git",
|
||||
branch = "v1.4.0",
|
||||
}
|
||||
description = {
|
||||
summary = "A simple API to use logging features",
|
||||
detailed = [[
|
||||
LuaLogging provides a simple API to use logging features in Lua. Its design was
|
||||
based on log4j. LuaLogging currently supports, through the use of appenders,
|
||||
console, file, rolling file, email, socket and SQL outputs.
|
||||
]],
|
||||
homepage = "https://github.com/lunarmodules/lualogging",
|
||||
license = "MIT/X11",
|
||||
}
|
||||
dependencies = {
|
||||
"luasocket"
|
||||
}
|
||||
build = {
|
||||
type = "none",
|
||||
install = {
|
||||
lua = {
|
||||
['logging'] = "src/logging.lua",
|
||||
['logging.console'] = "src/logging/console.lua",
|
||||
['logging.file'] = "src/logging/file.lua",
|
||||
['logging.rolling_file'] = "src/logging/rolling_file.lua",
|
||||
['logging.email'] = "src/logging/email.lua",
|
||||
['logging.sql'] = "src/logging/sql.lua",
|
||||
['logging.socket'] = "src/logging/socket.lua",
|
||||
}
|
||||
},
|
||||
copy_directories = {
|
||||
"docs",
|
||||
},
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
local package_name = "lualogging"
|
||||
local package_version = "1.5.0"
|
||||
local rockspec_revision = "1"
|
||||
local github_account_name = "lunarmodules"
|
||||
local github_repo_name = package_name
|
||||
|
||||
|
||||
package = package_name
|
||||
version = package_version.."-"..rockspec_revision
|
||||
source = {
|
||||
url = "git://github.com/"..github_account_name.."/"..github_repo_name..".git",
|
||||
tag = "v"..package_version
|
||||
}
|
||||
description = {
|
||||
summary = "A simple API to use logging features",
|
||||
detailed = [[
|
||||
LuaLogging provides a simple API to use logging features in Lua. Its design was
|
||||
based on log4j. LuaLogging currently supports, through the use of appenders,
|
||||
console, file, rolling file, email, socket and SQL outputs.
|
||||
]],
|
||||
homepage = "https://github.com/"..github_account_name.."/"..github_repo_name,
|
||||
license = "MIT/X11",
|
||||
}
|
||||
dependencies = {
|
||||
"luasocket"
|
||||
}
|
||||
build = {
|
||||
type = "none",
|
||||
install = {
|
||||
lua = {
|
||||
['logging'] = "src/logging.lua",
|
||||
['logging.console'] = "src/logging/console.lua",
|
||||
['logging.file'] = "src/logging/file.lua",
|
||||
['logging.rolling_file'] = "src/logging/rolling_file.lua",
|
||||
['logging.email'] = "src/logging/email.lua",
|
||||
['logging.sql'] = "src/logging/sql.lua",
|
||||
['logging.socket'] = "src/logging/socket.lua",
|
||||
}
|
||||
},
|
||||
copy_directories = {
|
||||
"docs",
|
||||
},
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
local package_name = "lualogging"
|
||||
local package_version = "1.5.1"
|
||||
local rockspec_revision = "1"
|
||||
local github_account_name = "lunarmodules"
|
||||
local github_repo_name = package_name
|
||||
|
||||
|
||||
package = package_name
|
||||
version = package_version.."-"..rockspec_revision
|
||||
source = {
|
||||
url = "git://github.com/"..github_account_name.."/"..github_repo_name..".git",
|
||||
tag = "v"..package_version
|
||||
}
|
||||
description = {
|
||||
summary = "A simple API to use logging features",
|
||||
detailed = [[
|
||||
LuaLogging provides a simple API to use logging features in Lua. Its design was
|
||||
based on log4j. LuaLogging currently supports, through the use of appenders,
|
||||
console, file, rolling file, email, socket and SQL outputs.
|
||||
]],
|
||||
homepage = "https://github.com/"..github_account_name.."/"..github_repo_name,
|
||||
license = "MIT/X11",
|
||||
}
|
||||
dependencies = {
|
||||
"luasocket"
|
||||
}
|
||||
build = {
|
||||
type = "none",
|
||||
install = {
|
||||
lua = {
|
||||
['logging'] = "src/logging.lua",
|
||||
['logging.console'] = "src/logging/console.lua",
|
||||
['logging.file'] = "src/logging/file.lua",
|
||||
['logging.rolling_file'] = "src/logging/rolling_file.lua",
|
||||
['logging.email'] = "src/logging/email.lua",
|
||||
['logging.sql'] = "src/logging/sql.lua",
|
||||
['logging.socket'] = "src/logging/socket.lua",
|
||||
}
|
||||
},
|
||||
copy_directories = {
|
||||
"docs",
|
||||
},
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
local package_name = "lualogging"
|
||||
local package_version = "1.5.2"
|
||||
local rockspec_revision = "1"
|
||||
local github_account_name = "lunarmodules"
|
||||
local github_repo_name = package_name
|
||||
|
||||
|
||||
package = package_name
|
||||
version = package_version.."-"..rockspec_revision
|
||||
source = {
|
||||
url = "git://github.com/"..github_account_name.."/"..github_repo_name..".git",
|
||||
tag = "v"..package_version
|
||||
}
|
||||
description = {
|
||||
summary = "A simple API to use logging features",
|
||||
detailed = [[
|
||||
LuaLogging provides a simple API to use logging features in Lua. Its design was
|
||||
based on log4j. LuaLogging currently supports, through the use of appenders,
|
||||
console, file, rolling file, email, socket and SQL outputs.
|
||||
]],
|
||||
homepage = "https://github.com/"..github_account_name.."/"..github_repo_name,
|
||||
license = "MIT/X11",
|
||||
}
|
||||
dependencies = {
|
||||
"luasocket"
|
||||
}
|
||||
build = {
|
||||
type = "none",
|
||||
install = {
|
||||
lua = {
|
||||
['logging'] = "src/logging.lua",
|
||||
['logging.console'] = "src/logging/console.lua",
|
||||
['logging.file'] = "src/logging/file.lua",
|
||||
['logging.rolling_file'] = "src/logging/rolling_file.lua",
|
||||
['logging.email'] = "src/logging/email.lua",
|
||||
['logging.sql'] = "src/logging/sql.lua",
|
||||
['logging.socket'] = "src/logging/socket.lua",
|
||||
}
|
||||
},
|
||||
copy_directories = {
|
||||
"docs",
|
||||
},
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
local package_name = "lualogging"
|
||||
local package_version = "1.6.0"
|
||||
local rockspec_revision = "1"
|
||||
local github_account_name = "lunarmodules"
|
||||
local github_repo_name = package_name
|
||||
|
||||
|
||||
package = package_name
|
||||
version = package_version.."-"..rockspec_revision
|
||||
source = {
|
||||
url = "git://github.com/"..github_account_name.."/"..github_repo_name..".git",
|
||||
branch = "master"
|
||||
}
|
||||
description = {
|
||||
summary = "A simple API to use logging features",
|
||||
detailed = [[
|
||||
LuaLogging provides a simple API to use logging features in Lua. Its design was
|
||||
based on log4j. LuaLogging currently supports, through the use of appenders,
|
||||
console, file, rolling file, email, socket and SQL outputs.
|
||||
]],
|
||||
homepage = "https://github.com/"..github_account_name.."/"..github_repo_name,
|
||||
license = "MIT/X11",
|
||||
}
|
||||
dependencies = {
|
||||
"luasocket"
|
||||
}
|
||||
build = {
|
||||
type = "none",
|
||||
install = {
|
||||
lua = {
|
||||
['logging'] = "src/logging.lua",
|
||||
['logging.console'] = "src/logging/console.lua",
|
||||
['logging.file'] = "src/logging/file.lua",
|
||||
['logging.rolling_file'] = "src/logging/rolling_file.lua",
|
||||
['logging.email'] = "src/logging/email.lua",
|
||||
['logging.sql'] = "src/logging/sql.lua",
|
||||
['logging.socket'] = "src/logging/socket.lua",
|
||||
['logging.nginx'] = "src/logging/nginx.lua",
|
||||
}
|
||||
},
|
||||
copy_directories = {
|
||||
"docs",
|
||||
},
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
local package_name = "lualogging"
|
||||
local package_version = "1.6.0"
|
||||
local rockspec_revision = "2"
|
||||
local github_account_name = "lunarmodules"
|
||||
local github_repo_name = package_name
|
||||
|
||||
|
||||
package = package_name
|
||||
version = package_version.."-"..rockspec_revision
|
||||
source = {
|
||||
url = "git://github.com/"..github_account_name.."/"..github_repo_name..".git",
|
||||
branch = (package_version == "dev") and "master" or nil,
|
||||
tag = (package_version ~= "dev") and ("v"..package_version) or nil,
|
||||
}
|
||||
description = {
|
||||
summary = "A simple API to use logging features",
|
||||
detailed = [[
|
||||
LuaLogging provides a simple API to use logging features in Lua. Its design was
|
||||
based on log4j. LuaLogging currently supports, through the use of appenders,
|
||||
console, file, rolling file, email, socket and SQL outputs.
|
||||
]],
|
||||
homepage = "https://github.com/"..github_account_name.."/"..github_repo_name,
|
||||
license = "MIT/X11",
|
||||
}
|
||||
dependencies = {
|
||||
"luasocket"
|
||||
}
|
||||
build = {
|
||||
type = "none",
|
||||
install = {
|
||||
lua = {
|
||||
['logging'] = "src/logging.lua",
|
||||
['logging.console'] = "src/logging/console.lua",
|
||||
['logging.file'] = "src/logging/file.lua",
|
||||
['logging.rolling_file'] = "src/logging/rolling_file.lua",
|
||||
['logging.email'] = "src/logging/email.lua",
|
||||
['logging.sql'] = "src/logging/sql.lua",
|
||||
['logging.socket'] = "src/logging/socket.lua",
|
||||
['logging.nginx'] = "src/logging/nginx.lua",
|
||||
}
|
||||
},
|
||||
copy_directories = {
|
||||
"docs",
|
||||
},
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
local package_name = "lualogging"
|
||||
local package_version = "1.7.0"
|
||||
local rockspec_revision = "1"
|
||||
local github_account_name = "lunarmodules"
|
||||
local github_repo_name = package_name
|
||||
|
||||
|
||||
package = package_name
|
||||
version = package_version.."-"..rockspec_revision
|
||||
source = {
|
||||
url = "git://github.com/"..github_account_name.."/"..github_repo_name..".git",
|
||||
branch = (package_version == "dev") and "master" or nil,
|
||||
tag = (package_version ~= "dev") and ("v"..package_version) or nil,
|
||||
}
|
||||
description = {
|
||||
summary = "A simple API to use logging features",
|
||||
detailed = [[
|
||||
LuaLogging provides a simple API to use logging features in Lua. Its design was
|
||||
based on log4j. LuaLogging currently supports, through the use of appenders,
|
||||
console, file, rolling file, email, socket and SQL outputs.
|
||||
]],
|
||||
homepage = "https://github.com/"..github_account_name.."/"..github_repo_name,
|
||||
license = "MIT/X11",
|
||||
}
|
||||
dependencies = {
|
||||
"luasocket"
|
||||
}
|
||||
build = {
|
||||
type = "none",
|
||||
install = {
|
||||
lua = {
|
||||
['logging'] = "src/logging.lua",
|
||||
['logging.console'] = "src/logging/console.lua",
|
||||
['logging.file'] = "src/logging/file.lua",
|
||||
['logging.rolling_file'] = "src/logging/rolling_file.lua",
|
||||
['logging.email'] = "src/logging/email.lua",
|
||||
['logging.sql'] = "src/logging/sql.lua",
|
||||
['logging.socket'] = "src/logging/socket.lua",
|
||||
['logging.nginx'] = "src/logging/nginx.lua",
|
||||
['logging.rsyslog'] = "src/logging/rsyslog.lua",
|
||||
}
|
||||
},
|
||||
copy_directories = {
|
||||
"docs",
|
||||
},
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
local package_name = "lualogging"
|
||||
local package_version = "1.8.0"
|
||||
local rockspec_revision = "1"
|
||||
local github_account_name = "lunarmodules"
|
||||
local github_repo_name = package_name
|
||||
|
||||
|
||||
package = package_name
|
||||
version = package_version.."-"..rockspec_revision
|
||||
source = {
|
||||
url = "git://github.com/"..github_account_name.."/"..github_repo_name..".git",
|
||||
branch = (package_version == "dev") and "master" or nil,
|
||||
tag = (package_version ~= "dev") and ("v"..package_version) or nil,
|
||||
}
|
||||
description = {
|
||||
summary = "A simple API to use logging features",
|
||||
detailed = [[
|
||||
LuaLogging provides a simple API to use logging features in Lua. Its design was
|
||||
based on log4j. LuaLogging currently supports, through the use of appenders,
|
||||
console, file, rolling file, email, socket and SQL outputs.
|
||||
]],
|
||||
homepage = "https://github.com/"..github_account_name.."/"..github_repo_name,
|
||||
license = "MIT/X11",
|
||||
}
|
||||
dependencies = {
|
||||
"luasocket"
|
||||
}
|
||||
build = {
|
||||
type = "none",
|
||||
install = {
|
||||
lua = {
|
||||
['logging'] = "src/logging.lua",
|
||||
['logging.console'] = "src/logging/console.lua",
|
||||
['logging.file'] = "src/logging/file.lua",
|
||||
['logging.rolling_file'] = "src/logging/rolling_file.lua",
|
||||
['logging.email'] = "src/logging/email.lua",
|
||||
['logging.sql'] = "src/logging/sql.lua",
|
||||
['logging.socket'] = "src/logging/socket.lua",
|
||||
['logging.nginx'] = "src/logging/nginx.lua",
|
||||
['logging.rsyslog'] = "src/logging/rsyslog.lua",
|
||||
['logging.envconfig'] = "src/logging/envconfig.lua",
|
||||
}
|
||||
},
|
||||
copy_directories = {
|
||||
"docs",
|
||||
},
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
local package_name = "lualogging"
|
||||
local package_version = "1.8.1"
|
||||
local rockspec_revision = "1"
|
||||
local github_account_name = "lunarmodules"
|
||||
local github_repo_name = package_name
|
||||
|
||||
|
||||
package = package_name
|
||||
version = package_version.."-"..rockspec_revision
|
||||
source = {
|
||||
url = "git://github.com/"..github_account_name.."/"..github_repo_name..".git",
|
||||
branch = (package_version == "dev") and "master" or nil,
|
||||
tag = (package_version ~= "dev") and ("v"..package_version) or nil,
|
||||
}
|
||||
description = {
|
||||
summary = "A simple API to use logging features",
|
||||
detailed = [[
|
||||
LuaLogging provides a simple API to use logging features in Lua. Its design was
|
||||
based on log4j. LuaLogging currently supports, through the use of appenders,
|
||||
console, file, rolling file, email, socket and SQL outputs.
|
||||
]],
|
||||
homepage = "https://github.com/"..github_account_name.."/"..github_repo_name,
|
||||
license = "MIT/X11",
|
||||
}
|
||||
dependencies = {
|
||||
"luasocket"
|
||||
}
|
||||
build = {
|
||||
type = "none",
|
||||
install = {
|
||||
lua = {
|
||||
['logging'] = "src/logging.lua",
|
||||
['logging.console'] = "src/logging/console.lua",
|
||||
['logging.file'] = "src/logging/file.lua",
|
||||
['logging.rolling_file'] = "src/logging/rolling_file.lua",
|
||||
['logging.email'] = "src/logging/email.lua",
|
||||
['logging.sql'] = "src/logging/sql.lua",
|
||||
['logging.socket'] = "src/logging/socket.lua",
|
||||
['logging.nginx'] = "src/logging/nginx.lua",
|
||||
['logging.rsyslog'] = "src/logging/rsyslog.lua",
|
||||
['logging.envconfig'] = "src/logging/envconfig.lua",
|
||||
}
|
||||
},
|
||||
copy_directories = {
|
||||
"docs",
|
||||
},
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
local package_name = "lualogging"
|
||||
local package_version = "1.8.2"
|
||||
local rockspec_revision = "1"
|
||||
local github_account_name = "lunarmodules"
|
||||
local github_repo_name = package_name
|
||||
|
||||
|
||||
package = package_name
|
||||
version = package_version.."-"..rockspec_revision
|
||||
source = {
|
||||
url = "git://github.com/"..github_account_name.."/"..github_repo_name..".git",
|
||||
branch = (package_version == "dev") and "master" or nil,
|
||||
tag = (package_version ~= "dev") and ("v"..package_version) or nil,
|
||||
}
|
||||
description = {
|
||||
summary = "A simple API to use logging features",
|
||||
detailed = [[
|
||||
LuaLogging provides a simple API to use logging features in Lua. Its design was
|
||||
based on log4j. LuaLogging currently supports, through the use of appenders,
|
||||
console, file, rolling file, email, socket and SQL outputs.
|
||||
]],
|
||||
homepage = "https://github.com/"..github_account_name.."/"..github_repo_name,
|
||||
license = "MIT/X11",
|
||||
}
|
||||
dependencies = {
|
||||
"luasocket"
|
||||
}
|
||||
build = {
|
||||
type = "none",
|
||||
install = {
|
||||
lua = {
|
||||
['logging'] = "src/logging.lua",
|
||||
['logging.console'] = "src/logging/console.lua",
|
||||
['logging.file'] = "src/logging/file.lua",
|
||||
['logging.rolling_file'] = "src/logging/rolling_file.lua",
|
||||
['logging.email'] = "src/logging/email.lua",
|
||||
['logging.sql'] = "src/logging/sql.lua",
|
||||
['logging.socket'] = "src/logging/socket.lua",
|
||||
['logging.nginx'] = "src/logging/nginx.lua",
|
||||
['logging.rsyslog'] = "src/logging/rsyslog.lua",
|
||||
['logging.envconfig'] = "src/logging/envconfig.lua",
|
||||
}
|
||||
},
|
||||
copy_directories = {
|
||||
"docs",
|
||||
},
|
||||
}
|
|
@ -0,0 +1,468 @@
|
|||
-------------------------------------------------------------------------------
|
||||
-- includes a new tostring function that handles tables recursively
|
||||
--
|
||||
-- @author Danilo Tuler (tuler@ideais.com.br)
|
||||
-- @author Andre Carregal (info@keplerproject.org)
|
||||
-- @author Thiago Costa Ponte (thiago@ideais.com.br)
|
||||
--
|
||||
-- @copyright 2004-2010 Kepler Project, 2011-2013 Neopallium, 2020-2023 Thijs Schreijer
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
local type, table, string, _tostring, tonumber = type, table, string, tostring, tonumber
|
||||
local select = select
|
||||
local error = error
|
||||
local format = string.format
|
||||
local floor = math.floor
|
||||
local pairs = pairs
|
||||
local ipairs = ipairs
|
||||
|
||||
local logging = {
|
||||
-- Meta information
|
||||
_COPYRIGHT = "Copyright (C) 2004-2010 Kepler Project, 2011-2013 Neopallium, 2020-2023 Thijs Schreijer",
|
||||
_DESCRIPTION = "A simple API to use logging features in Lua",
|
||||
_VERSION = "LuaLogging 1.8.2",
|
||||
}
|
||||
|
||||
local LEVELS = { "DEBUG", "INFO", "WARN", "ERROR", "FATAL", "OFF" }
|
||||
local MAX_LEVELS = #LEVELS
|
||||
for i, level in ipairs(LEVELS) do
|
||||
LEVELS[level] = i
|
||||
logging[level] = level
|
||||
end
|
||||
|
||||
local defaultLevel = LEVELS[1]
|
||||
local defaultLogPattern = "%date %level %message\n"
|
||||
local defaultLogPatterns = nil
|
||||
local defaultTimestampPattern = nil
|
||||
local defaultLogger = nil
|
||||
|
||||
local function rewrite_stacktrace()
|
||||
-- prettify stack-trace, remove lualogging entries and reformat to 1 line
|
||||
local result = ''
|
||||
local trace = debug and debug.traceback() or ''
|
||||
for entry in trace:gmatch("%s*(.-)\n") do
|
||||
if entry:match("%:%d+%:") and not entry:find('logging.lua') then
|
||||
result = result .. ' | ' .. entry
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
-- private log function, with support for formating a complex log message.
|
||||
local function LOG_MSG(self, level, fmt, ...)
|
||||
local f_type = type(fmt)
|
||||
if f_type == 'string' then
|
||||
if select('#', ...) > 0 then
|
||||
local status, msg = pcall(format, fmt, ...)
|
||||
if status then
|
||||
return self:append(level, msg)
|
||||
else
|
||||
return self:append(level, "Error formatting log message: " ..
|
||||
msg .. rewrite_stacktrace())
|
||||
end
|
||||
else
|
||||
-- only a single string, no formating needed.
|
||||
return self:append(level, fmt)
|
||||
end
|
||||
elseif f_type == 'function' then
|
||||
-- fmt should be a callable function which returns the message to log
|
||||
return self:append(level, fmt(...))
|
||||
end
|
||||
-- fmt is not a string and not a function, just call tostring() on it.
|
||||
return self:append(level, logging.tostring(fmt))
|
||||
end
|
||||
|
||||
-- do nothing function for disabled levels.
|
||||
local function disable_level() end
|
||||
|
||||
-- a generic print function that prints to the log
|
||||
local function print_to_log(logger, level, ...)
|
||||
local args = { n = select("#", ...), ... }
|
||||
for i = 1, args.n do args[i] = _tostring(args[i]) end
|
||||
args = table.concat(args, " ") .. "\n"
|
||||
for line in args:gmatch("(.-)\n") do
|
||||
logger:log(level, line)
|
||||
end
|
||||
end
|
||||
|
||||
-- improved assertion function.
|
||||
local function assert(exp, ...)
|
||||
-- if exp is true, we are finished so don't do any processing of the parameters
|
||||
if exp then return exp, ... end
|
||||
-- assertion failed, raise error
|
||||
error(format(...), 2)
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Creates a new logger object
|
||||
-- @param append Function used by the logger to append a message with a
|
||||
-- log-level to the log stream.
|
||||
-- @param startLevel log-level to start with
|
||||
-- @return Table representing the new logger object.
|
||||
-- @return String if there was any error setting the custom levels if provided
|
||||
-------------------------------------------------------------------------------
|
||||
function logging.new(append, startLevel)
|
||||
assert(type(append) == "function", "Appender must be a function, got: %s.", type(append))
|
||||
startLevel = startLevel or defaultLevel
|
||||
assert(LEVELS[startLevel], "startLevel must be a valid log-level constant if given")
|
||||
|
||||
local LEVEL_FUNCS = {}
|
||||
|
||||
local logger = {}
|
||||
logger.append = append
|
||||
|
||||
logger.setLevel = function (self, level)
|
||||
local order = LEVELS[level]
|
||||
assert(order, "undefined level '%s'", _tostring(level))
|
||||
local old_level = self.level
|
||||
self.level = level
|
||||
self.level_order = order
|
||||
-- enable/disable levels
|
||||
for i=1, MAX_LEVELS do
|
||||
local name = LEVELS[i]:lower()
|
||||
if i >= order and i ~= MAX_LEVELS then
|
||||
self[name] = LEVEL_FUNCS[i]
|
||||
else
|
||||
self[name] = disable_level
|
||||
end
|
||||
end
|
||||
if old_level and old_level ~= level then
|
||||
self:log(LEVELS[1], "Logger: changing loglevel from %s to %s", old_level, level)
|
||||
end
|
||||
end
|
||||
|
||||
-- generic log function.
|
||||
logger.log = function (self, level, ...)
|
||||
local order = LEVELS[level]
|
||||
assert(order, "undefined level `%s'", _tostring(level))
|
||||
if order < self.level_order then
|
||||
return
|
||||
end
|
||||
return LOG_MSG(self, level, ...)
|
||||
end
|
||||
|
||||
-- a print function generator
|
||||
logger.getPrint = function (self, level)
|
||||
local order = LEVELS[level]
|
||||
assert(order, "undefined level `%s'", _tostring(level))
|
||||
return function(...)
|
||||
if order >= self.level_order then
|
||||
print_to_log(self, level, ...)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- create the proxy functions for each log level.
|
||||
for i=1, MAX_LEVELS do
|
||||
local level = LEVELS[i]
|
||||
if logger[level:lower()] then
|
||||
return nil, "'" .. level .."' is not a proper level name since there is already a property '" .. level:lower() .. "'"
|
||||
end
|
||||
LEVEL_FUNCS[i] = function(self, ...)
|
||||
-- no level checking needed here, this function will only be called if it's level is active.
|
||||
return LOG_MSG(self, level, ...)
|
||||
end
|
||||
end
|
||||
|
||||
-- insert log level constants
|
||||
for i=1, MAX_LEVELS do
|
||||
logger[LEVELS[i]] = LEVELS[i]
|
||||
end
|
||||
|
||||
-- initialize log level.
|
||||
logger:setLevel(startLevel)
|
||||
return logger
|
||||
end
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Prepares the log message
|
||||
-------------------------------------------------------------------------------
|
||||
local sourceDebugLevel = 1 -- this will be set dynamically below
|
||||
local getDebugInfoLine = debug and "local info = debug.getinfo(%d)" or "local info = { short_src = '?', currentline = -1 }"
|
||||
|
||||
function logging.compilePattern(pattern)
|
||||
pattern = string.format("%q", pattern)
|
||||
|
||||
-- replace %source by its components first
|
||||
pattern = pattern:gsub("%%source", "%%file:%%line in function '%%function'")
|
||||
|
||||
local placeholders = {
|
||||
["date"] = false,
|
||||
["level"] = false,
|
||||
["message"] = false,
|
||||
-- truthy: requires debug info to be fetched first
|
||||
["file"] = "info.short_src",
|
||||
["line"] = "tostring(info.currentline)",
|
||||
["function"] = '(info.name or "unknown function")',
|
||||
}
|
||||
local inject_info = false
|
||||
for placeholder, needs_info in pairs(placeholders) do
|
||||
local count
|
||||
pattern, count = pattern:gsub("%%"..placeholder, '"..'..(needs_info or placeholder)..'.."')
|
||||
inject_info = inject_info or (count>0 and needs_info)
|
||||
end
|
||||
-- cleanup start & end
|
||||
if pattern:sub(1, 4) == '""..' then
|
||||
pattern = pattern:sub(5, -1)
|
||||
end
|
||||
if pattern:sub(-4, -1) == '..""' then
|
||||
pattern = pattern:sub(1, -5)
|
||||
end
|
||||
-- build function
|
||||
local func = [[
|
||||
return function(date, level, message)
|
||||
]]..(inject_info and getDebugInfoLine:format(sourceDebugLevel) or "")..[[
|
||||
|
||||
return ]]..pattern..[[
|
||||
|
||||
end]]
|
||||
|
||||
return (loadstring or load)(func, "lualogging_generated_formatter")()
|
||||
end
|
||||
|
||||
local clearCompiledCache
|
||||
do
|
||||
local cache = setmetatable({}, {
|
||||
__index = function(self, pattern)
|
||||
-- pattern wasn't found in cache, compile now, and cache format-function
|
||||
self[pattern] = logging.compilePattern(pattern)
|
||||
return self[pattern]
|
||||
end
|
||||
})
|
||||
|
||||
function clearCompiledCache()
|
||||
for k in pairs(cache) do cache[k] = nil end
|
||||
end
|
||||
|
||||
function logging.prepareLogMsg(lpattern, dpattern, level, message)
|
||||
return cache[lpattern](dpattern, level, message)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- os.date replacement with milliseconds if supported
|
||||
-- ms placeholder = %q or %xq (where x is number of decimals)
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
do
|
||||
local gettime = os.time
|
||||
local ok, socket = pcall(require, "socket") -- load luasocket if available
|
||||
if ok then
|
||||
gettime = socket.gettime
|
||||
end
|
||||
|
||||
-- use a pattern cache to know if we even need ms to format
|
||||
local patternCache = setmetatable({}, {
|
||||
__index = function(self, patt)
|
||||
local placeholder = patt:match("(%%%d*q)")
|
||||
if not placeholder then
|
||||
self[patt] = false
|
||||
return false
|
||||
end
|
||||
|
||||
local size = tonumber(placeholder:sub(2,-2)) or 3
|
||||
assert(size >= 1 and size <= 6, "millisecond format %q quantifier range is 1 to 6")
|
||||
self[patt] = ("0"):rep(size) -- a string to grab trailing "0"'s from
|
||||
return self[patt]
|
||||
end
|
||||
})
|
||||
function logging.date(fmt, t)
|
||||
fmt = fmt or "%c"
|
||||
t = t or gettime()
|
||||
local pad = patternCache[fmt]
|
||||
local ms
|
||||
if pad then
|
||||
-- ms required
|
||||
ms = math.fmod(t,1)
|
||||
local mss = (tostring(ms) .. pad):sub(3, -1)
|
||||
|
||||
fmt = fmt:gsub("(%%%d*q)", function(placeholder)
|
||||
return mss:sub(1, #pad)
|
||||
end)
|
||||
end
|
||||
|
||||
local res, err = os.date(fmt, floor(t)) -- 5.3+ requires t to be an integer
|
||||
if type(res) == "table" then
|
||||
res.secf = ms or math.fmod(t,1)
|
||||
end
|
||||
return res, err
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Converts a Lua value to a string
|
||||
--
|
||||
-- Converts Table fields in alphabetical order
|
||||
-------------------------------------------------------------------------------
|
||||
local function tostring(value)
|
||||
local str = ''
|
||||
|
||||
if (type(value) ~= 'table') then
|
||||
if (type(value) == 'string') then
|
||||
str = string.format("%q", value)
|
||||
else
|
||||
str = _tostring(value)
|
||||
end
|
||||
else
|
||||
local auxTable = {}
|
||||
for key in pairs(value) do
|
||||
if (tonumber(key) ~= key) then
|
||||
table.insert(auxTable, key)
|
||||
else
|
||||
table.insert(auxTable, tostring(key))
|
||||
end
|
||||
end
|
||||
table.sort(auxTable)
|
||||
|
||||
str = str..'{'
|
||||
local separator = ""
|
||||
local entry
|
||||
for _, fieldName in ipairs(auxTable) do
|
||||
if ((tonumber(fieldName)) and (tonumber(fieldName) > 0)) then
|
||||
entry = tostring(value[tonumber(fieldName)])
|
||||
else
|
||||
entry = fieldName.." = "..tostring(value[fieldName])
|
||||
end
|
||||
str = str..separator..entry
|
||||
separator = ", "
|
||||
end
|
||||
str = str..'}'
|
||||
end
|
||||
return str
|
||||
end
|
||||
logging.tostring = tostring
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Application level defaults
|
||||
-------------------------------------------------------------------------------
|
||||
function logging.defaultLogPatterns(patt)
|
||||
if patt then
|
||||
if type(patt) == "string" then
|
||||
patt = logging.buildLogPatterns({}, patt)
|
||||
end
|
||||
assert(type(patt) == "table", "logPatterns must be a string or a table, got: %s", type(patt))
|
||||
for _, level in ipairs(LEVELS) do
|
||||
if level ~= "OFF" then
|
||||
assert(type(patt[level]) == "string", "the patterns contains a '%s' value (instead of a string) for level '%s'", type(patt[level]), level)
|
||||
end
|
||||
end
|
||||
defaultLogPatterns = patt
|
||||
end
|
||||
return defaultLogPatterns
|
||||
end
|
||||
|
||||
function logging.defaultTimestampPattern(patt)
|
||||
if patt then
|
||||
if type(patt) ~= "string" then
|
||||
error("timestampPattern must be a string", 2)
|
||||
end
|
||||
defaultTimestampPattern = patt
|
||||
end
|
||||
return defaultTimestampPattern
|
||||
end
|
||||
|
||||
function logging.defaultLevel(level)
|
||||
if level then
|
||||
if not LEVELS[level] then
|
||||
assert(LEVELS[level], "undefined level '%s'", _tostring(level))
|
||||
end
|
||||
defaultLevel = level
|
||||
end
|
||||
return defaultLevel
|
||||
end
|
||||
|
||||
function logging.defaultLogger(logger)
|
||||
if logger then
|
||||
-- check getPrint to protect against accidental call using colon-notation
|
||||
if type(logger) ~= "table" or type(logger.getPrint) ~= "function" then
|
||||
error("expected a logger object", 2)
|
||||
end
|
||||
defaultLogger = logger
|
||||
end
|
||||
|
||||
if not defaultLogger then
|
||||
-- no default logger yet, go create it, using the current defaults
|
||||
defaultLogger = require("logging.console") { destination = "stderr" }
|
||||
end
|
||||
|
||||
return defaultLogger
|
||||
end
|
||||
|
||||
--- Returns a table of patterns, indexed by loglevel.
|
||||
-- @param patterns (table, optional) table containing logPattern strings per level, defaults to `{}`
|
||||
-- @param default (string, optional) the logPattern to be used for levels not yet present in 'patterns'.
|
||||
-- @return table, with a logPattern for every log-level constant
|
||||
function logging.buildLogPatterns(patterns, default)
|
||||
patterns = patterns or {}
|
||||
assert(type(default) == "string" or type(default) == "nil", "expected default logPattern (2nd argument) to be a string or nil, got: %s", tostring(default))
|
||||
assert(type(patterns) == "table", "expected patterns (1st argument) to be a table or nil, got: %s", tostring(patterns))
|
||||
local target = {}
|
||||
for _, level in ipairs(LEVELS) do
|
||||
if level ~= "OFF" then
|
||||
target[level] = patterns[level] or default or defaultLogPatterns[level]
|
||||
end
|
||||
end
|
||||
return target
|
||||
end
|
||||
|
||||
defaultLogPatterns = logging.buildLogPatterns({}, defaultLogPattern)
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Backward compatible parameter handling
|
||||
-------------------------------------------------------------------------------
|
||||
function logging.getDeprecatedParams(lst, ...) -- TODO: remove in next major version
|
||||
local args = { n = select("#", ...), ...}
|
||||
if type(args[1]) == "table" then
|
||||
-- this is the new format of a single params-table
|
||||
return args[1]
|
||||
end
|
||||
|
||||
local params = {}
|
||||
for i, param_name in ipairs(lst) do
|
||||
params[param_name] = args[i]
|
||||
end
|
||||
return params
|
||||
end
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- dynamically detect proper source debug level, since this can vary by Lua versions
|
||||
-------------------------------------------------------------------------------
|
||||
if debug then
|
||||
local detection_logger, test_msg
|
||||
|
||||
local function detect_func() detection_logger:debug("message") end -- This function MUST be on a single line!!
|
||||
local detect_func_info = debug.getinfo(detect_func)
|
||||
local detect_func_match = detect_func_info.short_src..":"..tostring(detect_func_info.linedefined or -999)
|
||||
|
||||
detection_logger = logging.new( function(self, level, message)
|
||||
test_msg = logging.prepareLogMsg("%source", "", level, message)
|
||||
end)
|
||||
|
||||
while true do
|
||||
if not pcall(detect_func) then
|
||||
-- cannot detect debug level, so set the function to fetch debug info to
|
||||
-- return a table that always returns "na" for each lookup
|
||||
getDebugInfoLine = "local info = setmetatable({}, { __index = function() return 'na' end })"
|
||||
break
|
||||
end
|
||||
|
||||
if test_msg:find(detect_func_match, 1, true) then
|
||||
break -- found correct level, done
|
||||
end
|
||||
-- move to next level
|
||||
sourceDebugLevel = sourceDebugLevel + 1
|
||||
clearCompiledCache()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
if _VERSION < 'Lua 5.2' then
|
||||
-- still create 'logging' global for Lua versions < 5.2
|
||||
_G.logging = logging
|
||||
end
|
||||
|
||||
return logging
|
|
@ -0,0 +1,53 @@
|
|||
-------------------------------------------------------------------------------
|
||||
-- Prints logging information to console
|
||||
--
|
||||
-- @author Thiago Costa Ponte (thiago@ideais.com.br)
|
||||
--
|
||||
-- @copyright 2004-2010 Kepler Project, 2011-2013 Neopallium, 2020-2023 Thijs Schreijer
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
local io = require"io"
|
||||
local logging = require"logging"
|
||||
local prepareLogMsg = logging.prepareLogMsg
|
||||
|
||||
|
||||
local destinations = setmetatable({
|
||||
stdout = "stdout",
|
||||
stderr = "stderr",
|
||||
},
|
||||
{
|
||||
__index = function(self, key)
|
||||
if not key then
|
||||
return "stdout" -- default value
|
||||
end
|
||||
error("destination parameter must be either 'stderr' or 'stdout', got: "..tostring(key), 3)
|
||||
end
|
||||
})
|
||||
|
||||
|
||||
local M = setmetatable({}, {
|
||||
__call = function(self, ...)
|
||||
-- calling on the module instantiates a new logger
|
||||
return self.new(...)
|
||||
end,
|
||||
})
|
||||
|
||||
|
||||
function M.new(params, ...)
|
||||
params = logging.getDeprecatedParams({ "logPattern" }, params, ...)
|
||||
local startLevel = params.logLevel or logging.defaultLevel()
|
||||
local timestampPattern = params.timestampPattern or logging.defaultTimestampPattern()
|
||||
local destination = destinations[params.destination]
|
||||
local logPatterns = logging.buildLogPatterns(params.logPatterns, params.logPattern)
|
||||
|
||||
return logging.new( function(self, level, message)
|
||||
io[destination]:write(prepareLogMsg(logPatterns[level], logging.date(timestampPattern), level, message))
|
||||
return true
|
||||
end, startLevel)
|
||||
end
|
||||
|
||||
|
||||
logging.console = M
|
||||
return M
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
-------------------------------------------------------------------------------
|
||||
-- Emails logging information to the given recipient
|
||||
--
|
||||
-- @author Thiago Costa Ponte (thiago@ideais.com.br)
|
||||
--
|
||||
-- @copyright 2004-2010 Kepler Project, 2011-2013 Neopallium, 2020-2023 Thijs Schreijer
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
local logging = require"logging"
|
||||
local smtp = require"socket.smtp"
|
||||
|
||||
|
||||
local M = setmetatable({}, {
|
||||
__call = function(self, ...)
|
||||
-- calling on the module instantiates a new logger
|
||||
return self.new(...)
|
||||
end,
|
||||
})
|
||||
|
||||
|
||||
function M.new(params)
|
||||
params = params or {}
|
||||
params.headers = params.headers or {}
|
||||
|
||||
if params.from == nil then
|
||||
return nil, "'from' parameter is required"
|
||||
end
|
||||
if params.rcpt == nil then
|
||||
return nil, "'rcpt' parameter is required"
|
||||
end
|
||||
|
||||
local timestampPattern = params.timestampPattern or logging.defaultTimestampPattern()
|
||||
local logPatterns = logging.buildLogPatterns(params.logPatterns, params.logPattern)
|
||||
local startLevel = params.logLevel or logging.defaultLevel()
|
||||
|
||||
return logging.new( function(self, level, message)
|
||||
local dt = logging.date(timestampPattern)
|
||||
local s = logging.prepareLogMsg(logPatterns[level], dt, level, message)
|
||||
if params.headers.subject then
|
||||
params.headers.subject =
|
||||
logging.prepareLogMsg(params.headers.subject, dt, level, message)
|
||||
end
|
||||
local msg = { headers = params.headers, body = s }
|
||||
params.source = smtp.message(msg)
|
||||
params.port = "25"
|
||||
|
||||
local r, e = smtp.send(params)
|
||||
if not r then
|
||||
return nil, e
|
||||
end
|
||||
|
||||
return true
|
||||
end, startLevel)
|
||||
end
|
||||
|
||||
|
||||
logging.email = M
|
||||
return M
|
|
@ -0,0 +1,194 @@
|
|||
-------------------------------------------------------------------------------
|
||||
-- Configures LuaLogging from the environment
|
||||
--
|
||||
-- @author Thijs Schreijer
|
||||
--
|
||||
-- @copyright 2004-2010 Kepler Project, 2011-2013 Neopallium, 2020-2023 Thijs Schreijer
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
local ll = require "logging"
|
||||
|
||||
local levels = { "DEBUG", "INFO", "WARN", "ERROR", "FATAL", "OFF" }
|
||||
local default_logger_name = "console"
|
||||
local default_logger_opts = { destination = "stderr" }
|
||||
local default_log_level = ll.defaultLevel()
|
||||
local default_timestamp_pattern = ll.defaultTimestampPattern()
|
||||
local default_prefix = "LL"
|
||||
|
||||
|
||||
-- -- Debug code to display environment variable access
|
||||
-- local getenv = os.getenv
|
||||
-- os.getenv = function(key)
|
||||
-- print(key.."="..tostring(getenv(key)))
|
||||
-- return getenv(key)
|
||||
-- end
|
||||
|
||||
local M = {}
|
||||
|
||||
local function validate_prefix(prefix)
|
||||
if type(prefix) ~= "string" then
|
||||
return nil, "expected prefix to be a string"
|
||||
end
|
||||
if prefix ~= prefix:gsub("[^0-9a-zA-Z_]", "") then
|
||||
return nil, "prefix can contain only A-Z, 0-9, and _"
|
||||
end
|
||||
if not prefix:match("^[a-zA-Z]") then
|
||||
return nil, "prefix must start with A-Z"
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
--- table that dynamically looks up environment variables.
|
||||
-- Keys must be strings "A-Z0-9_", and start with "A-Z". The lookup
|
||||
-- is case-insensitive, the environment variable MUST be in ALL CAPS.
|
||||
-- Values will be converted to boolean if "true"/"false" (case-insensitive), or
|
||||
-- to a number if a valid number.
|
||||
-- @tparam string prefix for the environment variables
|
||||
-- @return table
|
||||
local function envloader(prefix)
|
||||
assert(validate_prefix(prefix))
|
||||
prefix = prefix .. "_"
|
||||
|
||||
-- looking up in this table will fetch from the environment with the proper prefix
|
||||
-- will convert bools, numbers, "logLevel" and "logPatterns" to proper format
|
||||
--
|
||||
-- NOTE: its a meta-method; so cannot return nil+err, must throw errors!
|
||||
local env = setmetatable({}, {
|
||||
__index = function(self, key)
|
||||
if type(key) ~= "string" or
|
||||
key ~= key:gsub("[^0-9a-zA-Z_]", "") or
|
||||
#key == 0 then
|
||||
return nil
|
||||
end
|
||||
|
||||
local envvar = (prefix..key):upper()
|
||||
|
||||
-- log patterns table (special case)
|
||||
if key:lower() == "logpatterns" then
|
||||
local patt = {}
|
||||
for _, l in ipairs(levels) do
|
||||
local level = ll[l] -- the numeric constant for the level
|
||||
patt[level] = os.getenv(envvar.."_"..l)
|
||||
end
|
||||
|
||||
if not next(patt) then
|
||||
return nil -- none set, so return nil instead of empty table
|
||||
end
|
||||
return patt
|
||||
end
|
||||
|
||||
-- read the value
|
||||
local value = os.getenv(envvar)
|
||||
if value == nil then
|
||||
return value
|
||||
end
|
||||
|
||||
-- logLevel constants
|
||||
if key:lower() == "loglevel" then
|
||||
for _, l in ipairs(levels) do
|
||||
if value:upper() == l then
|
||||
return ll[value:upper()]
|
||||
end
|
||||
end
|
||||
error(("not a proper loglevel set in env var %s: '%s' (use one of: %s"):
|
||||
format(envvar, value, '"DEBUG", "INFO", "WARN", "ERROR", "FATAL", "OFF"'))
|
||||
end
|
||||
|
||||
-- check for boolean
|
||||
if value:lower() == "true" or value:lower() == "false" then
|
||||
return value:lower() == "true"
|
||||
end
|
||||
|
||||
-- check for number
|
||||
if value:gsub("[1-9%.%-]", "") == "" and
|
||||
#value - #value:gsub("[%.]", "") <= 1 and -- zero or 1 "." character
|
||||
(#value - #value:gsub("[%-]", "") == 0 or -- zero "-" characters
|
||||
#value - #value:gsub("[%-]", "") == 1 and value:match("^%-")) and -- 1 "-" character, at first pos
|
||||
#value - #value:gsub("[1-9]", "") >= 1 then -- at least 1 digit
|
||||
return tonumber(value)
|
||||
end
|
||||
|
||||
-- return as string
|
||||
return value
|
||||
end
|
||||
})
|
||||
|
||||
return env
|
||||
end
|
||||
|
||||
do
|
||||
local base_set = false
|
||||
local base_name
|
||||
local base_opts
|
||||
|
||||
--- Collects and sets the default logger and its option (does not create the logger).
|
||||
-- From an application, this is the first call to make, to set the "prefix" for the
|
||||
-- environment variables to use.
|
||||
-- @tparam prefix the prefix for env vars to use.
|
||||
-- @return true, or nil + err on failure
|
||||
function M.set_default_settings(prefix)
|
||||
if base_set then
|
||||
return nil, "already set a default"
|
||||
end
|
||||
local ok, err = validate_prefix(prefix)
|
||||
if not ok then
|
||||
return ok, err
|
||||
end
|
||||
base_opts = envloader(prefix)
|
||||
base_name = base_opts.logger
|
||||
if not base_name then
|
||||
-- no logger specified, so load options for default, and send defaults if absent
|
||||
base_name = default_logger_name
|
||||
for k, v in pairs(default_logger_opts) do
|
||||
local ev = base_opts[k]
|
||||
if ev == nil then -- false is a valid value, so check against nil
|
||||
ev = v
|
||||
end
|
||||
base_opts[k] = ev
|
||||
end
|
||||
end
|
||||
-- load additional standard options
|
||||
base_opts.logLevel = base_opts.logLevel or default_log_level
|
||||
base_opts.timestampPattern = base_opts.timestampPattern or default_timestamp_pattern
|
||||
base_opts.logPatterns = ll.buildLogPatterns(base_opts.logPatterns or {}, base_opts.logPattern)
|
||||
|
||||
base_set = true
|
||||
return true
|
||||
end
|
||||
|
||||
-- returns the loggername, and the options table for it
|
||||
function M.get_default_settings()
|
||||
if not base_set then
|
||||
assert(M.set_default_settings(default_prefix))
|
||||
end
|
||||
return base_name, base_opts
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--- Gets default logger options and then creates and sets the LuaLogging
|
||||
-- default logger. Should be called once, at application start. Not to be called by
|
||||
-- libraries, since this is an application global setting.
|
||||
-- @tparam[opt] string prefix if provided, then the default settings will be set
|
||||
-- using this prefix. If they were already set, it will return nil+err in that case.
|
||||
-- return default logger as set
|
||||
function M.set_default_logger(prefix)
|
||||
if prefix then
|
||||
local ok, err = M.set_default_settings(prefix)
|
||||
if not ok then
|
||||
return nil, err
|
||||
end
|
||||
end
|
||||
local name, opts = M.get_default_settings()
|
||||
|
||||
-- create the logger
|
||||
local logger = assert(require("logging."..name)(opts))
|
||||
-- set default and return it
|
||||
return ll.defaultLogger(logger)
|
||||
end
|
||||
|
||||
|
||||
|
||||
return M
|
|
@ -0,0 +1,80 @@
|
|||
-------------------------------------------------------------------------------
|
||||
-- Saves logging information in a file
|
||||
--
|
||||
-- @author Thiago Costa Ponte (thiago@ideais.com.br)
|
||||
--
|
||||
-- @copyright 2004-2010 Kepler Project, 2011-2013 Neopallium, 2020-2023 Thijs Schreijer
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
local logging = require"logging"
|
||||
|
||||
local lastFileNameDatePattern
|
||||
local lastFileHandler
|
||||
|
||||
|
||||
local buffer_mode do
|
||||
local dir_separator = _G.package.config:sub(1,1)
|
||||
local is_windows = dir_separator == '\\'
|
||||
if is_windows then
|
||||
-- Windows does not support "line" buffered mode, see
|
||||
-- https://github.com/lunarmodules/lualogging/pull/9
|
||||
buffer_mode = "no"
|
||||
else
|
||||
buffer_mode = "line"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local openFileLogger = function (filename, datePattern)
|
||||
local filename = string.format(filename, logging.date(datePattern))
|
||||
if (lastFileNameDatePattern ~= filename) then
|
||||
local f = io.open(filename, "a")
|
||||
if (f) then
|
||||
f:setvbuf(buffer_mode)
|
||||
lastFileNameDatePattern = filename
|
||||
lastFileHandler = f
|
||||
return f
|
||||
else
|
||||
return nil, string.format("file `%s' could not be opened for writing", filename)
|
||||
end
|
||||
else
|
||||
return lastFileHandler
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local M = setmetatable({}, {
|
||||
__call = function(self, ...)
|
||||
-- calling on the module instantiates a new logger
|
||||
return self.new(...)
|
||||
end,
|
||||
})
|
||||
|
||||
|
||||
function M.new(params, ...)
|
||||
params = logging.getDeprecatedParams({ "filename", "datePattern", "logPattern" }, params, ...)
|
||||
local filename = params.filename
|
||||
local datePattern = params.datePattern
|
||||
local logPatterns = logging.buildLogPatterns(params.logPatterns, params.logPattern)
|
||||
local timestampPattern = params.timestampPattern or logging.defaultTimestampPattern()
|
||||
local startLevel = params.logLevel or logging.defaultLevel()
|
||||
|
||||
if type(filename) ~= "string" then
|
||||
filename = "lualogging.log"
|
||||
end
|
||||
|
||||
return logging.new( function(self, level, message)
|
||||
local f, msg = openFileLogger(filename, datePattern)
|
||||
if not f then
|
||||
return nil, msg
|
||||
end
|
||||
local s = logging.prepareLogMsg(logPatterns[level], logging.date(timestampPattern), level, message)
|
||||
f:write(s)
|
||||
return true
|
||||
end, startLevel)
|
||||
end
|
||||
|
||||
|
||||
logging.file = M
|
||||
return M
|
|
@ -0,0 +1,55 @@
|
|||
-------------------------------------------------------------------------------
|
||||
-- Forwards logging information to the Nginx log
|
||||
--
|
||||
-- @author Thijs Schreijer
|
||||
--
|
||||
-- @copyright 2004-2010 Kepler Project, 2011-2013 Neopallium, 2020-2023 Thijs Schreijer
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
local logging = require "logging"
|
||||
local prepareLogMsg = logging.prepareLogMsg
|
||||
|
||||
local ngx_log = assert((ngx or {}).log, "this logger can only be used with OpenResty")
|
||||
|
||||
|
||||
local levels = {
|
||||
[logging.FATAL] = ngx.EMERG,
|
||||
[logging.ERROR] = ngx.ERR,
|
||||
[logging.WARN] = ngx.WARN,
|
||||
[logging.INFO] = ngx.INFO,
|
||||
[logging.DEBUG] = ngx.DEBUG,
|
||||
}
|
||||
|
||||
|
||||
local target_level do
|
||||
-- set the default lualogging level, based on the detected Nginx level
|
||||
local sys_log_level = require("ngx.errlog").get_sys_filter_level()
|
||||
for ll_level, ngx_level in pairs(levels) do
|
||||
if sys_log_level == ngx_level then
|
||||
target_level = ll_level
|
||||
ngx_log(ngx.DEBUG, "setting LuaLogging default level '", ll_level, "' to match Nginx level: ", ngx_level)
|
||||
break
|
||||
end
|
||||
end
|
||||
assert(target_level, "failed to map ngx log-level '"..tostring(sys_log_level).."' to a LuaLogging level")
|
||||
end
|
||||
|
||||
|
||||
local M = setmetatable({}, {
|
||||
__call = function(self, ...)
|
||||
-- calling on the module instantiates a new logger
|
||||
return self.new(...)
|
||||
end,
|
||||
})
|
||||
|
||||
|
||||
function M.new(params)
|
||||
return logging.new(function(self, level, message)
|
||||
return ngx_log(levels[level], prepareLogMsg("%message", "", level, message))
|
||||
end, target_level)
|
||||
end
|
||||
|
||||
|
||||
logging.nginx = M
|
||||
return M
|
|
@ -0,0 +1,109 @@
|
|||
---------------------------------------------------------------------------
|
||||
-- RollingFileAppender is a FileAppender that rolls over the logfile
|
||||
-- once it has reached a certain size limit. It also mantains a
|
||||
-- maximum number of log files.
|
||||
--
|
||||
-- @author Tiago Cesar Katcipis (tiagokatcipis@gmail.com)
|
||||
--
|
||||
-- @copyright 2004-2010 Kepler Project, 2011-2013 Neopallium, 2020-2023 Thijs Schreijer
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
local logging = require"logging"
|
||||
|
||||
|
||||
local buffer_mode do
|
||||
local dir_separator = _G.package.config:sub(1,1)
|
||||
local is_windows = dir_separator == '\\'
|
||||
if is_windows then
|
||||
-- Windows does not support "line" buffered mode, see
|
||||
-- https://github.com/lunarmodules/lualogging/pull/9
|
||||
buffer_mode = "no"
|
||||
else
|
||||
buffer_mode = "line"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function openFile(self)
|
||||
self.file = io.open(self.filename, "a")
|
||||
if not self.file then
|
||||
return nil, string.format("file `%s' could not be opened for writing", self.filename)
|
||||
end
|
||||
self.file:setvbuf(buffer_mode)
|
||||
return self.file
|
||||
end
|
||||
|
||||
|
||||
local rollOver = function (self)
|
||||
for i = self.maxIndex - 1, 1, -1 do
|
||||
-- files may not exist yet, lets ignore the possible errors.
|
||||
os.rename(self.filename.."."..tostring(i), self.filename.."."..tostring(i+1))
|
||||
end
|
||||
|
||||
self.file:close()
|
||||
self.file = nil
|
||||
|
||||
local _, msg = os.rename(self.filename, self.filename..".".."1")
|
||||
|
||||
if msg then
|
||||
return nil, string.format("error %s on log rollover", msg)
|
||||
end
|
||||
|
||||
return openFile(self)
|
||||
end
|
||||
|
||||
|
||||
local openRollingFileLogger = function (self)
|
||||
if not self.file then
|
||||
return openFile(self)
|
||||
end
|
||||
|
||||
local filesize = self.file:seek("end", 0)
|
||||
if not filesize then
|
||||
self.file:close()
|
||||
self.file = nil
|
||||
return openFile(self)
|
||||
end
|
||||
|
||||
if (filesize < self.maxSize) then
|
||||
return self.file
|
||||
end
|
||||
|
||||
return rollOver(self)
|
||||
end
|
||||
|
||||
|
||||
local M = setmetatable({}, {
|
||||
__call = function(self, ...)
|
||||
-- calling on the module instantiates a new logger
|
||||
return self.new(...)
|
||||
end,
|
||||
})
|
||||
|
||||
|
||||
function M.new(params, ...)
|
||||
params = logging.getDeprecatedParams({ "filename", "maxFileSize", "maxBackupIndex", "logPattern" }, params, ...)
|
||||
local logPatterns = logging.buildLogPatterns(params.logPatterns, params.logPattern)
|
||||
local timestampPattern = params.timestampPattern or logging.defaultTimestampPattern()
|
||||
local startLevel = params.logLevel or logging.defaultLevel()
|
||||
|
||||
local obj = {
|
||||
filename = type(params.filename) == "string" and params.filename or "lualogging.log",
|
||||
maxSize = params.maxFileSize,
|
||||
maxIndex = params.maxBackupIndex or 1
|
||||
}
|
||||
|
||||
return logging.new( function(self, level, message)
|
||||
local f, msg = openRollingFileLogger(obj)
|
||||
if not f then
|
||||
return nil, msg
|
||||
end
|
||||
local s = logging.prepareLogMsg(logPatterns[level], logging.date(timestampPattern), level, message)
|
||||
f:write(s)
|
||||
return true
|
||||
end, startLevel)
|
||||
end
|
||||
|
||||
|
||||
logging.rolling_file = M
|
||||
return M
|
|
@ -0,0 +1,376 @@
|
|||
-------------------------------------------------------------------------------
|
||||
-- Syslog for LuaLogging to a remote server using UDP/TCP
|
||||
--
|
||||
-- @author Thijs Schreijer
|
||||
--
|
||||
-- @copyright 2004-2010 Kepler Project, 2011-2013 Neopallium, 2020-2023 Thijs Schreijer
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
-- This module differs from [`LuaSyslog`](https://github.com/lunarmodules/luasyslog)
|
||||
-- in that it will log to a remote server, where `LuaSyslog` will log to the local
|
||||
-- syslog daemon.
|
||||
|
||||
|
||||
local socket = require "socket"
|
||||
local logging = require "logging"
|
||||
local prepareLogMsg = logging.prepareLogMsg
|
||||
local pcall = pcall
|
||||
|
||||
|
||||
local M = setmetatable({}, {
|
||||
__call = function(self, ...)
|
||||
-- calling on the module instantiates a new logger
|
||||
return self.new(...)
|
||||
end,
|
||||
})
|
||||
|
||||
|
||||
-- set on module table to be able to override it. For example with a Copas
|
||||
-- socket. No need for UDP, since UDP sending is non-blocking.
|
||||
M.tcp = socket.tcp
|
||||
|
||||
|
||||
local NILVALUE = "-"
|
||||
local MONTHS = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
||||
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }
|
||||
|
||||
|
||||
-- determine the local machine hostname, once at startup
|
||||
local HOSTNAME do
|
||||
if _G.package.config:sub(1,1) == "\\" then
|
||||
-- Windows
|
||||
HOSTNAME = os.getenv("COMPUTERNAME")
|
||||
else
|
||||
-- Unix like
|
||||
local f = io.popen ("/bin/hostname")
|
||||
HOSTNAME = f:read("*a")
|
||||
f:close()
|
||||
end
|
||||
|
||||
HOSTNAME = (HOSTNAME or ""):gsub("[^\33-\126]", "")
|
||||
|
||||
if HOSTNAME == "" then
|
||||
local s = socket.udp()
|
||||
s:setpeername("1.1.1.1",80) -- ip for cloudflare dns
|
||||
HOSTNAME = s:getsockname()
|
||||
end
|
||||
|
||||
HOSTNAME = (HOSTNAME or ""):gsub("[^\33-\126]", "")
|
||||
|
||||
if HOSTNAME == "" then
|
||||
HOSTNAME = NILVALUE
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- the syslog constants
|
||||
local syslog_facilities = {
|
||||
FACILITY_KERN = 0 * 8,
|
||||
FACILITY_USER = 1 * 8,
|
||||
FACILITY_MAIL = 2 * 8,
|
||||
FACILITY_DAEMON = 3 * 8,
|
||||
FACILITY_AUTH = 4 * 8,
|
||||
FACILITY_SYSLOG = 5 * 8,
|
||||
FACILITY_LPR = 6 * 8,
|
||||
FACILITY_NEWS = 7 * 8,
|
||||
FACILITY_UUCP = 8 * 8,
|
||||
FACILITY_CRON = 9 * 8,
|
||||
FACILITY_AUTHPRIV = 10 * 8,
|
||||
FACILITY_FTP = 11 * 8,
|
||||
FACILITY_NTP = 12 * 8,
|
||||
FACILITY_SECURITY = 13 * 8,
|
||||
FACILITY_CONSOLE = 14 * 8,
|
||||
FACILITY_NETINFO = 12 * 8,
|
||||
FACILITY_REMOTEAUTH = 13 * 8,
|
||||
FACILITY_INSTALL = 14 * 8,
|
||||
FACILITY_RAS = 15 * 8,
|
||||
FACILITY_LOCAL0 = 16 * 8,
|
||||
FACILITY_LOCAL1 = 17 * 8,
|
||||
FACILITY_LOCAL2 = 18 * 8,
|
||||
FACILITY_LOCAL3 = 19 * 8,
|
||||
FACILITY_LOCAL4 = 20 * 8,
|
||||
FACILITY_LOCAL5 = 21 * 8,
|
||||
FACILITY_LOCAL6 = 22 * 8,
|
||||
FACILITY_LOCAL7 = 23 * 8,
|
||||
}
|
||||
for k,v in pairs(syslog_facilities) do
|
||||
M[k] = v
|
||||
end
|
||||
|
||||
|
||||
|
||||
local syslog_levels = {
|
||||
LOG_EMERG = 0,
|
||||
LOG_ALERT = 1,
|
||||
LOG_CRIT = 2,
|
||||
LOG_ERR = 3,
|
||||
LOG_WARNING = 4,
|
||||
LOG_NOTICE = 5,
|
||||
LOG_INFO = 6,
|
||||
LOG_DEBUG = 7,
|
||||
}
|
||||
|
||||
|
||||
-- lookup table: convert lualogging level constant to syslog level constant
|
||||
local convert = {
|
||||
[logging.DEBUG] = syslog_levels.LOG_DEBUG,
|
||||
[logging.INFO] = syslog_levels.LOG_INFO,
|
||||
[logging.WARN] = syslog_levels.LOG_WARNING,
|
||||
[logging.ERROR] = syslog_levels.LOG_ERR,
|
||||
[logging.FATAL] = syslog_levels.LOG_ALERT,
|
||||
}
|
||||
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- Writer functions for both RFC's
|
||||
-- ---------------------------------------------------------------------------
|
||||
M.writers = {}
|
||||
|
||||
|
||||
function M.writers.rfc3164(prio, facility, ident, _, _, msg)
|
||||
local d = os.date("!*t")
|
||||
msg = msg:gsub("\n", "\\n"):gsub("\t", " "):gsub("\0-\31", "") -- higher bytes allowed, for UTF8... not according to spec
|
||||
return ("<%d>%s %2d %02d:%02d:%02d %s %s %s\n"):format(facility + prio, MONTHS[d.month], d.day, d.hour, d.min, d.sec, HOSTNAME, ident, msg)
|
||||
end
|
||||
|
||||
|
||||
function M.writers.rfc5424(prio, facility, ident, procid, msgid, msg)
|
||||
local timestamp = logging.date("!%Y-%m-%dT%H:%M:%S.%qZ")
|
||||
return ("<%d>1 %s %s %s %s %s - %s"):format(facility + prio, timestamp, HOSTNAME, ident, procid, msgid, msg)
|
||||
end
|
||||
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- sender functions for UDP and TCP
|
||||
-- ---------------------------------------------------------------------------
|
||||
|
||||
M.senders = {}
|
||||
|
||||
-- sockets indexed by cache-key.
|
||||
-- NOTE: sockets should be anchored on the logger object to prevent GC
|
||||
-- of active ones.
|
||||
local socket_cache = setmetatable({}, { __mode = "v" })
|
||||
|
||||
|
||||
|
||||
local function socket_error(self, err)
|
||||
io.stderr:write(err.."\n")
|
||||
return nil, err
|
||||
end
|
||||
|
||||
|
||||
|
||||
function M.senders.udp(self, msg, is_retry)
|
||||
local sock = self.socket
|
||||
if not sock then
|
||||
local cache_key = self.socket_cache_key
|
||||
sock = socket_cache[cache_key]
|
||||
if not sock then
|
||||
-- create a new socket
|
||||
local host, port = cache_key:match("^udp://(.+):(%d+)$")
|
||||
sock = assert(socket.udp())
|
||||
assert(sock:settimeout(5))
|
||||
local ok, err = sock:setpeername(host, tonumber(port))
|
||||
if not ok then
|
||||
return socket_error(self, "failed to connect to "..cache_key..": ".. tostring(err).."\n"..tostring(msg))
|
||||
end
|
||||
-- cache it
|
||||
socket_cache[cache_key] = sock
|
||||
end
|
||||
-- anchor it
|
||||
self.socket = sock
|
||||
end
|
||||
|
||||
local ok, err = sock:send(msg)
|
||||
if not ok then
|
||||
sock:close()
|
||||
self.socket = nil
|
||||
socket_cache[self.socket_cache_key] = nil
|
||||
-- recurse once; will recreate the socket and retry
|
||||
if not is_retry then
|
||||
return M.senders.udp(self, msg, true)
|
||||
else
|
||||
return socket_error(self, "failed to send msg (after retry) to "..self.socket_cache_key..": ".. tostring(err).."\n"..tostring(msg))
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
|
||||
function M.senders.tcp(self, msg, is_retry)
|
||||
local sock = self.socket
|
||||
if not sock then
|
||||
local cache_key = self.socket_cache_key
|
||||
sock = socket_cache[cache_key]
|
||||
if not sock then
|
||||
-- create a new socket
|
||||
local host, port = cache_key:match("^tcp://(.+):(%d+)$")
|
||||
sock = assert(M.tcp())
|
||||
assert(sock:settimeout(5))
|
||||
local ok, err = sock:connect(host, tonumber(port))
|
||||
if not ok then
|
||||
return socket_error(self, "failed to connect to "..cache_key..": ".. tostring(err).."\n"..tostring(msg))
|
||||
end
|
||||
ok, err = sock:setoption("keepalive", true)
|
||||
if not ok then
|
||||
return socket_error(self, "failed to set keepalive for "..cache_key..": ".. tostring(err).."\n"..tostring(msg))
|
||||
end
|
||||
-- cache it
|
||||
socket_cache[cache_key] = sock
|
||||
end
|
||||
-- anchor it
|
||||
self.socket = sock
|
||||
end
|
||||
|
||||
local payload
|
||||
if self.send_msg_size then
|
||||
payload = ("%d %s"):format(#msg, msg)
|
||||
else
|
||||
payload = msg.."\n" -- old RFC, terminate by LF
|
||||
end
|
||||
local last_byte_send = 0
|
||||
local size = #payload
|
||||
local err, last_send_error
|
||||
while last_byte_send < size do
|
||||
last_byte_send, err, last_send_error = sock:send(payload, last_byte_send + 1, size)
|
||||
if not last_byte_send then
|
||||
sock:close()
|
||||
self.socket = nil
|
||||
socket_cache[self.socket_cache_key] = nil
|
||||
-- recurse once; will recreate the socket and retry
|
||||
if not is_retry then
|
||||
return M.senders.tcp(self, msg, true)
|
||||
else
|
||||
return socket_error(self, "failed to send msg (after retry) to "..self.socket_cache_key.." ("..tostring(last_send_error).." bytes sent): ".. tostring(err).."\n"..tostring(msg))
|
||||
end
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
|
||||
function M.senders.copas(self, msg)
|
||||
local q = self.queue
|
||||
q:push(msg)
|
||||
if q:get_size() >= 1000 then
|
||||
-- queue is running full, drop an old message
|
||||
q:pop()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- instantiation
|
||||
-- ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
local function validate_facility(f)
|
||||
for k, v in pairs(syslog_facilities) do
|
||||
if v == f then
|
||||
if tostring(k):find("FACILITY_") then
|
||||
return f
|
||||
end
|
||||
end
|
||||
end
|
||||
return nil, "bad facility; " .. tostring(f)
|
||||
end
|
||||
|
||||
|
||||
local function copas_tcp()
|
||||
local copas = require("copas")
|
||||
return copas.wrap(socket.tcp())
|
||||
end
|
||||
|
||||
|
||||
function M.new(params, ...)
|
||||
params = logging.getDeprecatedParams({ "ident", "facility" }, params, ...)
|
||||
local logPatterns = logging.buildLogPatterns(params.logPatterns, params.logPattern or "%message")
|
||||
local startLevel = params.logLevel or logging.defaultLevel()
|
||||
local ident = (params.ident or "lua"):gsub("[^\33-\126]", "")
|
||||
assert(#ident > 0 and ident == (params.ident or "lua"), "invalid ident; invalid characters or empty")
|
||||
local procid = (params.procid or NILVALUE):gsub("[^\33-\126]", "")
|
||||
assert(#procid > 0 and procid == (params.procid or NILVALUE), "invalid procid; invalid characters or empty")
|
||||
local msgid = (params.msgid or NILVALUE):gsub("[^\33-\126]", "")
|
||||
assert(#msgid > 0 and msgid == (params.msgid or NILVALUE), "invalid msgid invalid characters or empty")
|
||||
local facility = assert(validate_facility(params.facility or syslog_facilities.FACILITY_USER))
|
||||
local maxsize = tonumber(params.maxsize)
|
||||
local write = assert(M.writers[params.rfc or "rfc3164"], "unsupported format: "..tostring(params.rfc))
|
||||
|
||||
if not maxsize then
|
||||
maxsize = 2048
|
||||
if params.rfc == "rfc3164" then
|
||||
maxsize = 1024
|
||||
end
|
||||
end
|
||||
assert(maxsize > 480, "expected maxsize to be a number > 480")
|
||||
|
||||
-- if send_msg_size is truthy then the message will be prefixed by the length. Otherwise
|
||||
-- an "\n" will be appended as separator. Only applies to TCP.
|
||||
local send_msg_size = false
|
||||
if params.rfc == "rfc5424" then
|
||||
send_msg_size = true
|
||||
end
|
||||
|
||||
local port = params.port or 514
|
||||
assert(type(port) == "number" and port > 0 and port < 65535, "not a valid port number: " .. tostring(params.port))
|
||||
local hostname = params.hostname
|
||||
assert(type(hostname) == "string", "expected 'hostname' to be a string")
|
||||
|
||||
local protocol = params.protocol
|
||||
local send = assert(M.senders[protocol or "tcp"], "unsupported protocol: "..tostring(protocol))
|
||||
if protocol == "tcp" and M.tcp == copas_tcp then
|
||||
-- copas was enabled, so use copas instead of tcp
|
||||
send = M.senders.copas
|
||||
end
|
||||
|
||||
local new_logger = logging.new(function(self, level, message)
|
||||
message = prepareLogMsg(logPatterns[level], "", level, message)
|
||||
message = write(convert[level], facility, ident, procid, msgid, message)
|
||||
|
||||
send(self, message:sub(1, maxsize))
|
||||
return true
|
||||
end, startLevel)
|
||||
|
||||
-- set some logger properties
|
||||
new_logger.socket_cache_key = ("%s://%s:%d"):format(protocol, hostname, port)
|
||||
new_logger.send_msg_size = send_msg_size
|
||||
|
||||
if protocol == "tcp" and M.tcp == copas_tcp then
|
||||
-- a copas sender, needs an async queue, and a worker to process the messages
|
||||
local queue = require("copas.queue").new {
|
||||
name = "lualogging-rsyslog"
|
||||
}
|
||||
local tcp_sender = M.senders.tcp
|
||||
queue:add_worker(function(msg)
|
||||
local ok, err = pcall(tcp_sender, new_logger, msg)
|
||||
if not ok then
|
||||
socket_error(new_logger, "lualogging rsyslog failed logging through Copas socket: "..tostring(err).."\n"..tostring(msg))
|
||||
end
|
||||
end)
|
||||
new_logger.queue = queue
|
||||
function new_logger:destroy()
|
||||
if self.queue then
|
||||
self.queue:stop()
|
||||
self.queue = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return new_logger
|
||||
end
|
||||
|
||||
function M.copas()
|
||||
if _VERSION=="Lua 5.1" and not jit then -- prevent yield across c-boundary
|
||||
pcall = require("coxpcall").pcall
|
||||
end
|
||||
|
||||
M.tcp = copas_tcp
|
||||
end
|
||||
|
||||
logging.rsyslog = M
|
||||
return M
|
|
@ -0,0 +1,50 @@
|
|||
-------------------------------------------------------------------------------
|
||||
-- Sends the logging information through a socket using luasocket
|
||||
--
|
||||
-- @author Thiago Costa Ponte (thiago@ideais.com.br)
|
||||
--
|
||||
-- @copyright 2004-2010 Kepler Project, 2011-2013 Neopallium, 2020-2023 Thijs Schreijer
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
local logging = require"logging"
|
||||
local socket = require"socket"
|
||||
|
||||
|
||||
local M = setmetatable({}, {
|
||||
__call = function(self, ...)
|
||||
-- calling on the module instantiates a new logger
|
||||
return self.new(...)
|
||||
end,
|
||||
})
|
||||
|
||||
|
||||
function M.new(params, ...)
|
||||
params = logging.getDeprecatedParams({ "hostname", "port", "logPattern" }, params, ...)
|
||||
local hostname = params.hostname
|
||||
local port = params.port
|
||||
local logPatterns = logging.buildLogPatterns(params.logPatterns, params.logPattern)
|
||||
local timestampPattern = params.timestampPattern or logging.defaultTimestampPattern()
|
||||
local startLevel = params.logLevel or logging.defaultLevel()
|
||||
|
||||
return logging.new( function(self, level, message)
|
||||
local s = logging.prepareLogMsg(logPatterns[level], logging.date(timestampPattern), level, message)
|
||||
|
||||
local socket, err = socket.connect(hostname, port)
|
||||
if not socket then
|
||||
return nil, err
|
||||
end
|
||||
|
||||
local cond, err = socket:send(s)
|
||||
if not cond then
|
||||
return nil, err
|
||||
end
|
||||
socket:close()
|
||||
|
||||
return true
|
||||
end, startLevel)
|
||||
end
|
||||
|
||||
|
||||
logging.socket = M
|
||||
return M
|
|
@ -0,0 +1,75 @@
|
|||
-------------------------------------------------------------------------------
|
||||
-- Saves the logging information in a table using luasql
|
||||
--
|
||||
-- @author Thiago Costa Ponte (thiago@ideais.com.br)
|
||||
--
|
||||
-- @copyright 2004-2010 Kepler Project, 2011-2013 Neopallium, 2020-2023 Thijs Schreijer
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
local logging = require"logging"
|
||||
|
||||
|
||||
local M = setmetatable({}, {
|
||||
__call = function(self, ...)
|
||||
-- calling on the module instantiates a new logger
|
||||
return self.new(...)
|
||||
end,
|
||||
})
|
||||
|
||||
|
||||
function M.new(params)
|
||||
params = params or {}
|
||||
params.tablename = params.tablename or "LogTable"
|
||||
params.logdatefield = params.logdatefield or "LogDate"
|
||||
params.loglevelfield = params.loglevelfield or "LogLevel"
|
||||
params.logmessagefield = params.logmessagefield or "LogMessage"
|
||||
|
||||
local startLevel = params.logLevel or logging.defaultLevel()
|
||||
|
||||
if params.connectionfactory == nil or type(params.connectionfactory) ~= "function" then
|
||||
return nil, "No specified connection factory function"
|
||||
end
|
||||
|
||||
local con, err
|
||||
if params.keepalive then
|
||||
con, err = params.connectionfactory()
|
||||
end
|
||||
|
||||
return logging.new( function(self, level, message)
|
||||
if (not params.keepalive) or (con == nil) then
|
||||
con, err = params.connectionfactory()
|
||||
if not con then
|
||||
return nil, err
|
||||
end
|
||||
end
|
||||
|
||||
local logDate = os.date("%Y-%m-%d %H:%M:%S")
|
||||
local insert = string.format("INSERT INTO %s (%s, %s, %s) VALUES ('%s', '%s', '%s')",
|
||||
params.tablename, params.logdatefield, params.loglevelfield,
|
||||
params.logmessagefield, logDate, level, string.gsub(message, "'", "''"))
|
||||
|
||||
local ret = pcall(con.execute, con, insert)
|
||||
if not ret then
|
||||
con, err = params.connectionfactory()
|
||||
if not con then
|
||||
return nil, err
|
||||
end
|
||||
ret, err = con:execute(insert)
|
||||
if not ret then
|
||||
return nil, err
|
||||
end
|
||||
end
|
||||
|
||||
if not params.keepalive then
|
||||
con:close()
|
||||
end
|
||||
|
||||
return true
|
||||
end, startLevel)
|
||||
end
|
||||
|
||||
|
||||
logging.sql = M
|
||||
return M
|
||||
|
|
@ -0,0 +1,249 @@
|
|||
local logging = require "logging"
|
||||
local call_count
|
||||
local last_msg
|
||||
local msgs
|
||||
|
||||
function logging.test(params)
|
||||
local logPatterns = logging.buildLogPatterns(params.logPatterns, params.logPattern)
|
||||
local timestampPattern = params.timestampPattern or logging.defaultTimestampPattern()
|
||||
return logging.new( function(self, level, message)
|
||||
last_msg = logging.prepareLogMsg(logPatterns[level], os.date(timestampPattern), level, message)
|
||||
msgs = msgs or {}
|
||||
table.insert(msgs, last_msg)
|
||||
--print("----->",last_msg)
|
||||
call_count = call_count + 1
|
||||
return true
|
||||
end)
|
||||
end
|
||||
|
||||
local function reset()
|
||||
call_count = 0
|
||||
last_msg = nil
|
||||
msgs = nil
|
||||
end
|
||||
|
||||
local tests = {}
|
||||
|
||||
|
||||
|
||||
|
||||
tests.constants_for_lualogging = function()
|
||||
local DEFAULT_LEVELS = { "DEBUG", "INFO", "WARN", "ERROR", "FATAL", "OFF" }
|
||||
for _, level in ipairs(DEFAULT_LEVELS) do
|
||||
assert(logging[level], "constant logging."..level.." is not defined")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
tests.deprecated_parameter_handling = function()
|
||||
local list = { "param1", "next_one", "hello_world" }
|
||||
local params = logging.getDeprecatedParams(list, {
|
||||
param1 = 1,
|
||||
next_one = nil,
|
||||
hello_world = 3,
|
||||
})
|
||||
assert(params.param1 == 1)
|
||||
assert(params.next_one == nil)
|
||||
assert(params.hello_world == 3)
|
||||
|
||||
params = logging.getDeprecatedParams(list, 1, nil, 3)
|
||||
assert(params.param1 == 1)
|
||||
assert(params.next_one == nil)
|
||||
assert(params.hello_world == 3)
|
||||
end
|
||||
|
||||
tests.buildLogPatterns = function()
|
||||
local check_patterns = function(t)
|
||||
assert(type(t) == "table")
|
||||
assert(t.DEBUG and t.INFO and t.WARN and t.ERROR and t.FATAL)
|
||||
local i = 0
|
||||
for k,v in pairs(t) do i = i + 1 end
|
||||
assert(i == 5)
|
||||
end
|
||||
local t = logging.buildLogPatterns()
|
||||
check_patterns(t)
|
||||
local t = logging.buildLogPatterns(nil, "hello")
|
||||
check_patterns(t)
|
||||
assert(t.DEBUG == "hello")
|
||||
assert(t.FATAL == "hello")
|
||||
local t = logging.buildLogPatterns({}, "hello")
|
||||
check_patterns(t)
|
||||
assert(t.DEBUG == "hello")
|
||||
assert(t.FATAL == "hello")
|
||||
local t = logging.buildLogPatterns({
|
||||
DEBUG = "bye"
|
||||
}, "hello")
|
||||
check_patterns(t)
|
||||
assert(t.DEBUG == "bye")
|
||||
assert(t.INFO == "hello")
|
||||
assert(t.FATAL == "hello")
|
||||
end
|
||||
|
||||
tests.log_levels = function()
|
||||
local logger = logging.test { logPattern = "%message", timestampPattern = nil }
|
||||
logger:setLevel(logger.DEBUG)
|
||||
-- debug gets logged
|
||||
logger:debug("message 1")
|
||||
assert(last_msg == "message 1", "got: " .. tostring(last_msg))
|
||||
assert(call_count == 1, "Got: " .. tostring(call_count))
|
||||
-- fatal also gets logged at 'debug' setting
|
||||
logger:fatal("message 2")
|
||||
assert(last_msg == "message 2", "got: " .. tostring(last_msg))
|
||||
assert(call_count == 2, "Got: " .. tostring(call_count))
|
||||
|
||||
logger:setLevel(logger.FATAL)
|
||||
-- debug gets logged
|
||||
logger:debug("message 3") -- should not change the last message
|
||||
assert(last_msg == "message 2", "got: " .. tostring(last_msg))
|
||||
assert(call_count == 2, "Got: " .. tostring(call_count))
|
||||
-- fatal also gets logged at 'debug' setting
|
||||
logger:fatal("message 4") -- should be logged as 3rd message
|
||||
assert(last_msg == "message 4", "got: " .. tostring(last_msg))
|
||||
assert(call_count == 3, "Got: " .. tostring(call_count))
|
||||
|
||||
logger:setLevel(logger.OFF)
|
||||
-- debug gets logged
|
||||
logger:debug("message 5") -- should not change the last message
|
||||
assert(last_msg == "message 4", "got: " .. tostring(last_msg))
|
||||
assert(call_count == 3, "Got: " .. tostring(call_count))
|
||||
-- fatal also gets logged at 'debug' setting
|
||||
logger:fatal("message 6") -- should not change the last message
|
||||
assert(last_msg == "message 4", "got: " .. tostring(last_msg))
|
||||
assert(call_count == 3, "Got: " .. tostring(call_count))
|
||||
-- should never log "OFF", even if its set
|
||||
logger:fatal("message 7") -- should not change the last message
|
||||
assert(last_msg == "message 4", "got: " .. tostring(last_msg))
|
||||
assert(call_count == 3, "Got: " .. tostring(call_count))
|
||||
end
|
||||
|
||||
|
||||
tests.logPatterns = function()
|
||||
local logger = logging.test { logPattern = "%date", timestampPattern = nil }
|
||||
logger:debug("hello")
|
||||
assert(last_msg ~= "%date", "expected '%date' placeholder to be replaced, got: " .. tostring(last_msg))
|
||||
assert(last_msg ~= "", "expected '%date' placeholder to be replaced by a value, got an empty string")
|
||||
|
||||
local logger = logging.test { logPattern = "%level", timestampPattern = nil }
|
||||
logger:fatal("hello")
|
||||
assert(last_msg ~= "%level", "expected '%level' placeholder to be replaced, got: " .. tostring(last_msg))
|
||||
assert(last_msg == "FATAL", "expected '%level' placeholder to be replaced by 'FATAL', got: " .. tostring(last_msg))
|
||||
|
||||
local logger = logging.test { logPattern = "%message", timestampPattern = nil }
|
||||
logger:debug("hello")
|
||||
assert(last_msg ~= "%message", "expected '%message' placeholder to be replaced, got: " .. tostring(last_msg))
|
||||
assert(last_msg == "hello", "expected '%message' placeholder to be replaced by 'hello', got: " .. tostring(last_msg))
|
||||
|
||||
local logger = logging.test { logPattern = "%source", timestampPattern = nil }
|
||||
local function test_func()
|
||||
logger:debug("hello")
|
||||
end
|
||||
test_func()
|
||||
assert(last_msg ~= "%source", "expected '%source' placeholder to be replaced, got: " .. tostring(last_msg))
|
||||
if debug then
|
||||
assert(last_msg:find("'test_func'", 1, true), "expected function name in output, got: " .. tostring(last_msg))
|
||||
assert(last_msg:find(":138 ", 1, true), "expected line number in output, got: " .. tostring(last_msg)) -- update hardcoded linenumber when this fails!
|
||||
assert(last_msg:find("generic.lua:", 1, true), "expected filename in output, got: " .. tostring(last_msg))
|
||||
else
|
||||
-- debug library disabled
|
||||
assert(last_msg:find("'unknown function'", 1, true), "expected 'unknwon function' in output, got: " .. tostring(last_msg))
|
||||
assert(last_msg:find(":-1 ", 1, true), "expected line number (-1) in output, got: " .. tostring(last_msg)) -- update hardcoded linenumber when this fails!
|
||||
assert(last_msg:find("?:", 1, true), "expected filename ('?') in output, got: " .. tostring(last_msg))
|
||||
end
|
||||
-- mutiple separate patterns
|
||||
local logger = logging.test {
|
||||
logPattern = "%message",
|
||||
logPatterns = {
|
||||
[logging.DEBUG] = "hello %message"
|
||||
},
|
||||
timestampPattern = nil,
|
||||
}
|
||||
logger:debug("world")
|
||||
assert(last_msg == "hello world", "expected 'hello world', got: " .. tostring(last_msg))
|
||||
logger:error("world")
|
||||
assert(last_msg == "world", "expected 'world', got: " .. tostring(last_msg))
|
||||
end
|
||||
|
||||
|
||||
tests.table_serialization = function()
|
||||
local logger = logging.test { logPattern = "%message", timestampPattern = nil }
|
||||
|
||||
logger:debug({1,2,3,4,5,6,7,8,9,10})
|
||||
assert(last_msg == "{1, 10, 2, 3, 4, 5, 6, 7, 8, 9}", "got: " .. tostring(last_msg))
|
||||
|
||||
logger:debug({abc = "cde", "hello", "world", xyz = true, 1, 2, 3})
|
||||
assert(last_msg == '{"hello", "world", 1, 2, 3, abc = "cde", xyz = true}', "got: " .. tostring(last_msg))
|
||||
end
|
||||
|
||||
|
||||
tests.print_function = function()
|
||||
local logger = logging.test { logPattern = "%level %message" }
|
||||
local print = logger:getPrint(logger.DEBUG)
|
||||
print("hey", "there", "dude")
|
||||
assert(msgs[1] == "DEBUG hey there dude")
|
||||
print()
|
||||
assert(msgs[2] == "DEBUG ")
|
||||
print("hello\nthere")
|
||||
assert(msgs[3] == "DEBUG hello")
|
||||
assert(msgs[4] == "DEBUG there")
|
||||
print({}, true, nil, 0)
|
||||
assert(msgs[5]:find("table"))
|
||||
assert(msgs[5]:find(" true nil 0$"))
|
||||
end
|
||||
|
||||
|
||||
tests.format_error_stacktrace = function()
|
||||
local count = 0
|
||||
local logger = logging.test { logPattern = "%level %message" }
|
||||
|
||||
logger:debug("%s-%s", 'abc', '007')
|
||||
assert(last_msg == 'DEBUG abc-007')
|
||||
|
||||
logger:debug("%s=%s", nil)
|
||||
assert(last_msg:find("bad argument #%d to '(.-)'"), "msg:'"..last_msg.."'")
|
||||
if debug then
|
||||
assert(last_msg:find("in main chunk"), "msg:'"..last_msg.."'")
|
||||
assert(last_msg:find("in %w+ 'func'"), "msg:'"..last_msg.."'")
|
||||
local _, levels = last_msg:gsub("(|)", function() count = count + 1 end)
|
||||
assert(levels == 3, "got : " .. tostring(levels))
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
tests.defaultLogger = function()
|
||||
-- returns a logger
|
||||
assert(logging.defaultLogger(), "expected a logger object to be returned)")
|
||||
local logger = logging.test {}
|
||||
-- setting a default one
|
||||
assert(logging.defaultLogger(logger), "expected a logger object to be returned)")
|
||||
assert(logger == logging.defaultLogger(), "expected my previously set logger to be returned)")
|
||||
end
|
||||
|
||||
|
||||
tests.defaultLevel = function()
|
||||
-- default level is 'debug'
|
||||
local old_level = logging.defaultLevel()
|
||||
assert(old_level == logging.DEBUG, "expected default to be 'debug'")
|
||||
-- setting level
|
||||
assert(logging.defaultLevel(logging.FATAL) == logging.FATAL, "expected updated log-level")
|
||||
-- new logger uses new default level
|
||||
local logger = logging.test {}
|
||||
logger:error("less than 'fatal', should not be logged")
|
||||
assert(call_count == 0)
|
||||
logger:fatal("should be logged")
|
||||
assert(call_count == 1)
|
||||
|
||||
-- errors on unknown level
|
||||
assert(not pcall(logging.defaultLevel, "unknown level"), "expected an error to be thrown")
|
||||
|
||||
-- restore old default
|
||||
logging.defaultLevel(old_level)
|
||||
end
|
||||
|
||||
|
||||
for name, func in pairs(tests) do
|
||||
reset()
|
||||
print("generic test: " .. name)
|
||||
func()
|
||||
end
|
||||
|
||||
print("[v] all generic tests succesful")
|
|
@ -0,0 +1,8 @@
|
|||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
LUA_PATH="../src/?.lua;$LUA_PATH" lua test.lua
|
||||
|
||||
rm -f test.db test.log*
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
|
||||
local test = {
|
||||
"generic.lua",
|
||||
"testEnv.lua",
|
||||
"testConsole.lua",
|
||||
"testFile.lua",
|
||||
"testMail.lua",
|
||||
"testSocket.lua",
|
||||
"testSQL.lua",
|
||||
"testRollingFile.lua",
|
||||
}
|
||||
|
||||
print ("Start of Logging tests")
|
||||
for _, filename in ipairs(test) do
|
||||
dofile(filename)
|
||||
end
|
||||
print ("End of Logging tests")
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
local log_console = require"logging.console"
|
||||
|
||||
local logger = log_console()
|
||||
|
||||
logger:info("logging.console test")
|
||||
logger:debug("debugging...")
|
||||
logger:error("error!")
|
||||
logger:debug("string with %4")
|
||||
logger:setLevel("INFO") -- test log level change warning.
|
||||
|
||||
print("Console Logging OK")
|
||||
|
|
@ -0,0 +1,145 @@
|
|||
local logging
|
||||
local logenv
|
||||
local env
|
||||
|
||||
local old_getenv = os.getenv
|
||||
function os.getenv(key) -- luacheck: ignore
|
||||
assert(type(key) == "string", "expected env variable name to be a string")
|
||||
return env[key]
|
||||
end
|
||||
|
||||
local function reset()
|
||||
env = {}
|
||||
package.loaded["logging"] = nil
|
||||
package.loaded["logging.envconfig"] = nil
|
||||
logging = require "logging"
|
||||
logenv = require "logging.envconfig"
|
||||
end
|
||||
|
||||
|
||||
local tests = {}
|
||||
|
||||
tests.returns_defaults = function()
|
||||
local name, opts = logenv.get_default_settings()
|
||||
-- print("title: ", require("pl.pretty").write(opts))
|
||||
assert(name == "console", "expected 'console' to be the default logger")
|
||||
assert(type(opts) == "table", "expected 'opts' to be a table")
|
||||
assert(opts.destination == "stderr", "expected 'destination' to be 'stderr'")
|
||||
assert(opts.logLevel == "DEBUG", "expected 'logLevel' to be 'DEBUG'")
|
||||
assert(opts.logPatterns.DEBUG == "%date %level %message\n")
|
||||
assert(opts.logPatterns.INFO == "%date %level %message\n")
|
||||
assert(opts.logPatterns.WARN == "%date %level %message\n")
|
||||
assert(opts.logPatterns.ERROR == "%date %level %message\n")
|
||||
assert(opts.logPatterns.FATAL == "%date %level %message\n")
|
||||
end
|
||||
|
||||
tests.returns_defaults_if_prefix_not_found = function()
|
||||
assert(logenv.set_default_settings("not_a_real_prefix"))
|
||||
local name, opts = logenv.get_default_settings()
|
||||
-- print("title: ", require("pl.pretty").write(opts))
|
||||
assert(name == "console", "expected 'console' to be the default logger")
|
||||
assert(type(opts) == "table", "expected 'opts' to be a table")
|
||||
assert(opts.destination == "stderr", "expected 'destination' to be 'stderr'")
|
||||
assert(opts.logLevel == "DEBUG", "expected 'logLevel' to be 'DEBUG'")
|
||||
assert(opts.logPatterns.DEBUG == "%date %level %message\n")
|
||||
assert(opts.logPatterns.INFO == "%date %level %message\n")
|
||||
assert(opts.logPatterns.WARN == "%date %level %message\n")
|
||||
assert(opts.logPatterns.ERROR == "%date %level %message\n")
|
||||
assert(opts.logPatterns.FATAL == "%date %level %message\n")
|
||||
end
|
||||
|
||||
tests.fails_if_default_already_set = function()
|
||||
assert(logenv.set_default_settings("prefix"))
|
||||
local ok, err = logenv.set_default_settings("prefix")
|
||||
assert(err == "already set a default")
|
||||
assert(ok == nil)
|
||||
end
|
||||
|
||||
tests.prefix_defaults_to_LL = function()
|
||||
env.LL_LOGLEVEL = assert(logging.ERROR)
|
||||
local _, opts = logenv.get_default_settings()
|
||||
-- print("title: ", require("pl.pretty").write(opts))
|
||||
assert(opts.logLevel == "ERROR", "expected 'logLevel' to be 'ERROR'")
|
||||
end
|
||||
|
||||
tests.loads_patterns_object = function()
|
||||
env.LL_LOGPATTERN = "not used"
|
||||
env.LL_LOGPATTERNS_DEBUG = "debug"
|
||||
env.LL_LOGPATTERNS_INFO = "info"
|
||||
env.LL_LOGPATTERNS_WARN = "warn"
|
||||
env.LL_LOGPATTERNS_ERROR = "error"
|
||||
env.LL_LOGPATTERNS_FATAL = "fatal"
|
||||
local _, opts = logenv.get_default_settings()
|
||||
-- print("title: ", require("pl.pretty").write(opts))
|
||||
assert(opts.logPattern == "not used")
|
||||
assert(opts.logPatterns.DEBUG == "debug")
|
||||
assert(opts.logPatterns.INFO == "info")
|
||||
assert(opts.logPatterns.WARN == "warn")
|
||||
assert(opts.logPatterns.ERROR == "error")
|
||||
assert(opts.logPatterns.FATAL == "fatal")
|
||||
end
|
||||
|
||||
tests.fills_patterns_object_from_logpattern = function()
|
||||
env.LL_LOGPATTERN = "this one"
|
||||
local _, opts = logenv.get_default_settings()
|
||||
-- print("title: ", require("pl.pretty").write(opts))
|
||||
assert(opts.logPattern == "this one")
|
||||
assert(opts.logPatterns.DEBUG == "this one")
|
||||
assert(opts.logPatterns.INFO == "this one")
|
||||
assert(opts.logPatterns.WARN == "this one")
|
||||
assert(opts.logPatterns.ERROR == "this one")
|
||||
assert(opts.logPatterns.FATAL == "this one")
|
||||
end
|
||||
|
||||
tests.bad_loglevel_not_accepted = function()
|
||||
env.LL_LOGLEVEL = "something bad"
|
||||
local ok, loggername, opts = pcall(logenv.get_default_settings)
|
||||
-- print("title: ", require("pl.pretty").write(opts))
|
||||
assert(not ok)
|
||||
assert(opts == nil)
|
||||
assert(type(loggername) == "string")
|
||||
end
|
||||
|
||||
tests.does_dynamic_lookups_of_vars = function()
|
||||
local _, opts = logenv.get_default_settings() -- "LL" is now prefix
|
||||
-- print("title: ", require("pl.pretty").write(opts))
|
||||
env.LL_SOME_VALUE = "hello"
|
||||
assert(opts.some_value == "hello")
|
||||
end
|
||||
|
||||
tests.converts_booleans = function()
|
||||
local _, opts = logenv.get_default_settings() -- "LL" is now prefix
|
||||
-- print("title: ", require("pl.pretty").write(opts))
|
||||
env.LL_ONE = "TRUE"
|
||||
env.LL_TWO = "true"
|
||||
env.LL_THREE = "false"
|
||||
env.LL_FOUR = "FALSE"
|
||||
assert(opts.one == true)
|
||||
assert(opts.two == true)
|
||||
assert(opts.three == false)
|
||||
assert(opts.four == false)
|
||||
end
|
||||
|
||||
tests.converts_numbers = function()
|
||||
local _, opts = logenv.get_default_settings() -- "LL" is now prefix
|
||||
env.LL_ONE = "1"
|
||||
env.LL_TWO = "-2"
|
||||
env.LL_THREE = ".2"
|
||||
env.LL_FOUR = "1.2"
|
||||
assert(opts.one == 1, "got: "..tostring(opts.one).." ("..type(opts.one)..")")
|
||||
assert(opts.two == -2, "got: "..tostring(opts.two).." ("..type(opts.two)..")")
|
||||
assert(opts.three == .2, "got: "..tostring(opts.three).." ("..type(opts.three)..")")
|
||||
assert(opts.four == 1.2, "got: "..tostring(opts.four).." ("..type(opts.four)..")")
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
for name, func in pairs(tests) do
|
||||
reset()
|
||||
print("env-config test: " .. name)
|
||||
func()
|
||||
end
|
||||
|
||||
print("[v] all env-config tests succesful")
|
||||
os.getenv = old_getenv -- luacheck: ignore
|
|
@ -0,0 +1,81 @@
|
|||
local GLOBAL_OS_DATE = os.date
|
||||
local GLOBAL_IO_OPEN = io.open
|
||||
|
||||
local buffer_mode do
|
||||
local dir_separator = _G.package.config:sub(1,1)
|
||||
local is_windows = dir_separator == '\\'
|
||||
if is_windows then
|
||||
-- Windows does not support "line" buffered mode, see
|
||||
-- https://github.com/lunarmodules/lualogging/pull/9
|
||||
buffer_mode = "no"
|
||||
else
|
||||
buffer_mode = "line"
|
||||
end
|
||||
end
|
||||
|
||||
local mock = {
|
||||
date = nil,
|
||||
handle = {}
|
||||
}
|
||||
|
||||
io.open = function (file, mode) --luacheck: ignore
|
||||
if (not string.find(file, "^__TEST*")) then
|
||||
return GLOBAL_IO_OPEN(file, mode)
|
||||
end
|
||||
|
||||
mock.handle[file] = {}
|
||||
mock.handle[file].lines = {}
|
||||
mock.handle[file].mode = mode
|
||||
return {
|
||||
setvbuf = function (_, s)
|
||||
mock.handle[file].setvbuf = s
|
||||
end,
|
||||
write = function (_, s)
|
||||
table.insert(mock.handle[file].lines, s)
|
||||
end,
|
||||
}
|
||||
end
|
||||
|
||||
os.date = function (...) --luacheck: ignore
|
||||
return mock.date
|
||||
end
|
||||
|
||||
local log_file = require "logging.file"
|
||||
|
||||
mock.date = "2008-01-01"
|
||||
local logger = log_file("__TEST%s.log", "%Y-%m-%d")
|
||||
|
||||
assert(mock.handle["__TEST"..mock.date..".log"] == nil)
|
||||
|
||||
logger:info("logging.file test")
|
||||
|
||||
assert(mock.handle["__TEST"..mock.date..".log"].mode == "a")
|
||||
assert(#mock.handle["__TEST"..mock.date..".log"].lines == 1)
|
||||
assert(mock.handle["__TEST"..mock.date..".log"].setvbuf == buffer_mode)
|
||||
assert(mock.handle["__TEST"..mock.date..".log"].lines[1] == "2008-01-01 INFO logging.file test\n")
|
||||
|
||||
mock.date = "2008-01-02"
|
||||
|
||||
logger:debug("debugging...")
|
||||
logger:error("error!")
|
||||
|
||||
assert(mock.handle["__TEST"..mock.date..".log"].mode == "a")
|
||||
assert(#mock.handle["__TEST"..mock.date..".log"].lines == 2)
|
||||
assert(mock.handle["__TEST"..mock.date..".log"].setvbuf == buffer_mode)
|
||||
assert(mock.handle["__TEST"..mock.date..".log"].lines[1] == "2008-01-02 DEBUG debugging...\n")
|
||||
assert(mock.handle["__TEST"..mock.date..".log"].lines[2] == "2008-01-02 ERROR error!\n")
|
||||
|
||||
mock.date = "2008-01-03"
|
||||
|
||||
logger:info({id = "1"})
|
||||
|
||||
assert(mock.handle["__TEST"..mock.date..".log"].mode == "a")
|
||||
assert(#mock.handle["__TEST"..mock.date..".log"].lines == 1)
|
||||
assert(mock.handle["__TEST"..mock.date..".log"].setvbuf == buffer_mode)
|
||||
assert(mock.handle["__TEST"..mock.date..".log"].lines[1] == '2008-01-03 INFO {id = "1"}\n')
|
||||
|
||||
os.date = GLOBAL_OS_DATE --luacheck: ignore
|
||||
io.open = GLOBAL_IO_OPEN --luacheck: ignore
|
||||
|
||||
print("File Logging OK")
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
local log_email = require"logging.email"
|
||||
|
||||
local logger = log_email {
|
||||
rcpt = "mail@host.com",
|
||||
from = "mail@host.com",
|
||||
{
|
||||
subject = "[%level] logging.email test",
|
||||
}, -- headers
|
||||
}
|
||||
|
||||
logger:info("logging.email test")
|
||||
logger:debug("debugging...")
|
||||
logger:error("error!")
|
||||
|
||||
print("Mail Logging OK")
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
local log_file = require "logging.rolling_file"
|
||||
|
||||
local max_size = 1024 * 10 --10kb
|
||||
local max_index = 5
|
||||
local total_log_size = max_size * max_index --more than needed because of the log pattern
|
||||
local log_filename = "test.log"
|
||||
local logger = log_file(log_filename, max_size, max_index)
|
||||
|
||||
|
||||
-- it will generate the log + max_index backup files
|
||||
local size = 0
|
||||
while size < total_log_size do
|
||||
local data = string.format("Test actual size[%d]", size)
|
||||
logger:debug(data)
|
||||
size = size + #data
|
||||
end
|
||||
|
||||
-- lets test if all files where created
|
||||
for i = 1, max_index do
|
||||
local file = assert(io.open(log_filename.."."..tostring(i), "r"))
|
||||
-- since there is an exact precision on the rolling
|
||||
-- (it can be a little less or a little more than the max_size)
|
||||
-- lets just test if the file is empty.
|
||||
|
||||
assert(file:seek("end", 0) > 0)
|
||||
file:close()
|
||||
end
|
||||
|
||||
print("RollingFile Logging OK")
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
local log_sql = require "logging.sql"
|
||||
local _, luasql = pcall(require, "luasql")
|
||||
local has_module = pcall(require, "luasql.sqlite3")
|
||||
if not has_module then
|
||||
print("SQLite 3 Logging SKIP (missing luasql.sqlite3)")
|
||||
else
|
||||
if not luasql or not luasql.sqlite3 then
|
||||
print("Missing LuaSQL SQLite 3 driver!")
|
||||
else
|
||||
local env = luasql.sqlite3()
|
||||
|
||||
local logger = log_sql{
|
||||
connectionfactory = function()
|
||||
return assert(env:connect("test.db"))
|
||||
end,
|
||||
keepalive = true,
|
||||
}
|
||||
|
||||
logger:info("logging.sql test")
|
||||
logger:debug("debugging...")
|
||||
logger:error("error!")
|
||||
print("SQLite 3 Logging OK")
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
local log_sock = require"logging.socket"
|
||||
|
||||
local logger = log_sock("localhost", "5000")
|
||||
|
||||
logger:info("logging.socket test")
|
||||
logger:debug("debugging...")
|
||||
logger:error("error!")
|
||||
|
||||
print("Socket Logging OK")
|
||||
|
Loading…
Reference in New Issue