Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/khuongduybui/fresh-logging
Access Log middleware for Deno Fresh
https://github.com/khuongduybui/fresh-logging
deno fresh logging
Last synced: 11 days ago
JSON representation
Access Log middleware for Deno Fresh
- Host: GitHub
- URL: https://github.com/khuongduybui/fresh-logging
- Owner: khuongduybui
- License: mit
- Created: 2022-10-11T03:49:36.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2023-12-15T08:40:16.000Z (about 1 year ago)
- Last Synced: 2025-01-16T23:07:58.942Z (26 days ago)
- Topics: deno, fresh, logging
- Language: TypeScript
- Homepage: https://deno.land/x/fresh_logging
- Size: 77.1 KB
- Stars: 3
- Watchers: 3
- Forks: 1
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# fresh-logging
[Access Log](https://www.w3.org/Daemon/User/Config/Logging.html#common-logfile-format) [middleware](https://fresh.deno.dev/docs/concepts/middleware) for
[Deno Fresh](https://fresh.deno.dev/).## Installation
First of all, create [your fresh app](https://fresh.deno.dev/docs/getting-started/create-a-project).
Add logging to your `import_map.json`.
```json
{
"imports": {
"$logging/": "https://deno.land/x/[email protected]/"
}
}
```Consume the logger in your app's `routes/_middleware.ts`.
```ts
import * as getLogger from "$logging/index.ts";
// or
// import { getLogger, ... } from "$logging/index.ts";export const handler = [
getLogger(),
// ... other middlewares
];
```**Note**: if `includeDuration` option is ON, `getLogger()` will also count the time taken by all of its subsequent middlewares. For example, putting
`getLogger()` at the beginning of your `handler` array will count the time taken by all middlewares, while putting it at the very end of your `handler` array
will yield the time taken only by the route handler.## Options
`getLogger()` accepts an optional object `{}` with the following options:
| Option | Default Value | Notes |
| ----------------- | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `format` | `LoggingFormat.COMMON` | The log format to use, defaulting to the [W3C Common Log Format](https://www.w3.org/Daemon/User/Config/Logging.html#common-logfile-format). |
| `utcTime` | `false` | Whether to log timestamps in UTC or server timezone. |
| `includeDuration` | `false` | Whether to include handler response time. |
| `resolvers` | `{}` | Selectively supply customer resolvers for the missing fields. See the next section on [limitations](#limitations) for more details. |
| `logger` | `console.info` +color -level | Optionally supply a custom logger function of type `(message: string) => string`. See the [logger section](#how-to-use-custom-logger) for more details. |
| `combinedHeaders` | ["Referer", "User-agent"] | Optionally supply custom request headers to include. Requires setting `format: LoggingFormat.APACHE_COMBINED`. |## Limitations
As of v1.1.2, the following fields are **completely** omitted (hard-coded to `-`):
- `rfc931` (client identifier): not sure how to obtain this
- `authuser` (user identifier): not sure how to obtain this either
- `bytes` (response content length): one way I can think of is to use `res.clone()` then read its as `ArrayBuffer` and get the `byteLength`, but that is both
time and memory consuming. Until I can find a more efficient way to obtain this piece of information, omission is the decision.Users can use the `resolvers` to provide custom resolutions of the missing fields. For example, the following code snippet allows logging the response bytes:
```ts
import { getLogger, ResolutionField } from "$logging/index.ts";export const handler = [
getLogger({
resolvers: {
[ResolutionField.bytes]: async (_req, _ctx, res) => `${(await res.clone().arrayBuffer()).byteLength}`,
},
}),
];
```Again, please note that the example above only serves to illustrate how to provide customer resolvers for the missing fields, the actual implementation is
sub-optimal. Otherwise, it would have been included as default resolver for that field.## How to use custom logger
Simply provide the `logger` option a function with the signature `(message: string) => string`, such as:
```ts
import { getLogger } from "$logging/index.ts";export const handler = [
getLogger({
logger: (message: string) => {
console.debug(message);
return message;
},
}),
];
```In combination with a sophisticated logging solution such as https://github.com/onjara/optic, most logging use cases (console/stdout, rotating file, cloud,
etc.) can be implemented with relative ease.## Use [Apache Combined Log Format](https://httpd.apache.org/docs/2.4/logs.html#:~:text=%25B%20instead.-,Combined%20Log%20Format,-Another%20commonly%20used)
Specify `LoggingFormat.APACHE_COMBINED` for the `format` option like this:
```ts
import { getLogger, LoggingFormat } from "$logging/index.ts";export const handler = [
getLogger({
format: LoggingFormat.APACHE_COMBINED,
}),
];
```The default two headers included are "Referer" and "User-agent". You can override that by optionally providing the `combinedHeaders` option, which expects a
string array of length 2.## A note about versioning
For now, the versions are `a.b.c-x.y.z` where `a.b.c` is the plugin version and `x.y.z` is the supported Turnstile API version. For example, `0.0.1-0` is the
initial release of plugin, which supports Turnstile API v0.All tags starting with `0.0.` are **mutable**. Expect breaking changes! Starting from `0.1.`, tags will be **immutable**. However, still expect breaking
changes. Starting from `1.`, semver will kick in and there will be no breaking changes until `2.`.