Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/haraka/haraka-results
Results storage for Haraka connections & transactions
https://github.com/haraka/haraka-results
haraka json pub-sub redis-client results
Last synced: about 2 months ago
JSON representation
Results storage for Haraka connections & transactions
- Host: GitHub
- URL: https://github.com/haraka/haraka-results
- Owner: haraka
- License: mit
- Created: 2017-01-26T08:24:45.000Z (almost 8 years ago)
- Default Branch: master
- Last Pushed: 2024-04-10T20:52:40.000Z (9 months ago)
- Last Synced: 2024-10-28T17:14:43.797Z (2 months ago)
- Topics: haraka, json, pub-sub, redis-client, results
- Language: JavaScript
- Homepage: https://www.npmjs.com/package/haraka-results
- Size: 61.5 KB
- Stars: 3
- Watchers: 5
- Forks: 6
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# haraka-results
[![Build Status][ci-img]][ci-url]
[![Code Coverage][cov-img]][cov-url]
[![Code Climate][clim-img]][clim-url]
[![NPM][npm-img]][npm-url]Add, log, retrieve, and share the results of plugin tests.
## Synopsis
Results is a structured way of storing results from plugins across a
session, allowing those results to be retrieved later or by other plugins.Results objects are present on every Haraka connection _and_ transaction. When
in a SMTP transaction, results from _both_ are applicable to that transaction.## Usage
Use results in your plugins like so:
```js
exports.my_first_hook = function (next, connection) {// run a test
......// store the results
connection.results.add(this, {pass: 'my great test' })// run another test
.....// store the results
connection.results.add(this, {fail: 'gotcha!', msg: 'show this'})
}
```Store the results in the transaction (vs connection):
```js
connection.transaction.results.add(this, {...});`
```### Config options
Each plugin can have custom settings in results.ini to control results logging.
There are three options available: hide, order, and debug.- hide - a comma separated list of results to hide from the output
- order - a comman separated list, specifing the order of items in the output
- debug - log debug messages every time results are called```ini
; put this in config/results.ini
[plugin_name]
hide=skip
order=msg,pass,fail
debug=0
```### Results Functions
#### add
Store information. Most calls to `results` will append data to the lists
in the connection. The following lists are available:pass - names of tests that passed
fail - names of tests that failed
skip - names of tests that were skipped (with a why, if you wish)
err - error messages encountered during processing
msg - arbitratry messageshuman - a custom summary to return (bypass collate)
emit - log an INFO summaryWhen err results are received, a logerror is automatically emitted, saving the
need to specify {emit: true} with the request.Examples:
```js
const results = connection.results
results.add(this, {pass: 'null_sender'})
results.add(this, {fail: 'single_recipient'})
results.add(this, {skip: 'valid_bounce'}
results.add(this, {err: 'timed out looking in couch cushions'})
results.add(this, {msg: 'I found a nickel!', emit: true})
```In addition to appending values to the predefined lists, arbitrary results
can be stored in the cache:```js
results.add(this, { my_result: 'anything I want' })
```When arbirary values are stored, they are listed first in the log output. Their
display can be suppressed with the **hide** option in results.ini.#### incr
Increment counters. The argument to incr is an object with counter names and
increment values. Examples:```js
results.incr(this, { unrecognized_commands: 1 })results.incr(this, { karma: -1 })
results.incr(this, { karma: 2 })
```#### push
Append items onto arrays. The argument to push is an object with array names and
the new value to be appended to the array. Examples:```js
results.push(this, { dns_recs: 'name1' })
results.push(this, { dns_recs: 'name2' })
```#### collate
```js
const summary = results.collate(this)
```Formats the contents of the result cache and returns them. This function is
called internally by `add()` after each update.#### get
Retrieve the stored results as an object. The only argument is the name of the
plugin whose results are desired.```js
const geoip = results.get('geoip')
if (geoip && geoip.distance && geoip.distance > 2000) {
....
}
```Keep in mind that plugins also store results in the transaction. Example:
```js
const sa = connection.transaction.results.get('spamassassin')
if (sa && sa.score > 5) {
....
}
```#### has
Check result contents for string or pattern matches.
Syntax:
```js
results.has('plugin_name', 'result_name', 'search_term')
```- result_name: the name of an array or string in the result object
- search_term: a string or RegExp object### More Examples
#### Store Results:
```js
results.add(this, { pass: 'some_test' })
results.add(this, { pass: 'some_test(with reason)' })
```#### Retrieve exact match with **get**:
```js
if (results.get('plugin_name').pass.indexOf('some_test') !== -1) {
// some_test passed (1x)
}
```#### Retrieve a string match with **has**
```js
if (results.has('plugin_name', 'pass', 'some_test')) {
// some_test passed (1x)
}
```The syntax for using **has** is a little more pleasant.
Both options require one to check for each reason which is unpleasant when
and all we really want to know is if some_test passed or not.#### Retrieve a matching pattern:
```js
if (results.has('plugin_name', 'pass', /^some_test/)) {
// some_test passed (2x)
}
```### Private Results
To store structured data in results that are hidden from the human and
human_html output, prefix the name of the key with an underscore.Example:
```js
results.add(this, { _hidden: 'some data' })
```## Redis Pub/Sub
If a redis client is found on server.notes.redis, then new results are JSON
encoded and published to Redis on the channel named `result-${UUID}`. This
feature can be disabled by setting `[main]redis_publish=false` in results.ini.
Plugins can recieve the events by psubscribing (pattern subscribe) to the
channel named `result-${UUID}*` where ${UUID} is the connection UUID.This is from the karma plugin subscribing on the `connect_init` hook:
```js
exports.register = function (next, server) {
this.inherits('redis')register_hook('connect_init', 'redis_subscribe')
register_hook('disconnect', 'redis_unsubscribe')
}exports.redis_subscribe = function (next, connection) {
this.redis_subscribe(connection, function () {
connection.notes.redis.on('pmessage', (pattern, channel, message) => {
// do stuff with messages that look like this
// {"plugin":"karma","result":{"fail":"spamassassin.hits"}}
// {"plugin":"geoip","result":{"country":"CN"}}
})
next()
})
}
exports.redis_unsubscribe = function (next, connection) {
this.redis_unsubscribe(connection)
}
```[ci-img]: https://github.com/haraka/haraka-results/actions/workflows/ci.yml/badge.svg
[ci-url]: https://github.com/haraka/haraka-results/actions/workflows/ci.yml
[cov-img]: https://codecov.io/github/haraka/haraka-results/coverage.svg
[cov-url]: https://codecov.io/github/haraka/haraka-results
[clim-img]: https://codeclimate.com/github/haraka/haraka-results/badges/gpa.svg
[clim-url]: https://codeclimate.com/github/haraka/haraka-results
[npm-img]: https://nodei.co/npm/haraka-results.png
[npm-url]: https://www.npmjs.com/package/haraka-results