slonik
Advanced tools
Comparing version 8.3.2 to 8.4.0
@@ -8,10 +8,20 @@ "use strict"; | ||
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; } | ||
var _crackJson = require("crack-json"); | ||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } | ||
var _isAutoExplainJsonMessage = _interopRequireDefault(require("./isAutoExplainJsonMessage")); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
const formatNotice = notice => { | ||
return _objectSpread({}, JSON.parse(JSON.stringify(notice)), { | ||
if ((0, _isAutoExplainJsonMessage.default)(notice.message)) { | ||
return { | ||
level: notice.name, | ||
message: (0, _crackJson.extractJson)(notice.message)[0] | ||
}; | ||
} | ||
return { | ||
level: notice.name, | ||
message: notice.message | ||
}); | ||
}; | ||
}; | ||
@@ -18,0 +28,0 @@ |
@@ -30,2 +30,8 @@ "use strict"; | ||
}); | ||
Object.defineProperty(exports, "isAutoExplainJsonMessage", { | ||
enumerable: true, | ||
get: function () { | ||
return _isAutoExplainJsonMessage.default; | ||
} | ||
}); | ||
Object.defineProperty(exports, "mapTaggedTemplateLiteralInvocation", { | ||
@@ -64,2 +70,4 @@ enumerable: true, | ||
var _isAutoExplainJsonMessage = _interopRequireDefault(require("./isAutoExplainJsonMessage")); | ||
var _mapTaggedTemplateLiteralInvocation = _interopRequireDefault(require("./mapTaggedTemplateLiteralInvocation")); | ||
@@ -66,0 +74,0 @@ |
@@ -16,2 +16,3 @@ { | ||
"boolean": "^0.2.0", | ||
"crack-json": "^1.1.0", | ||
"es6-error": "^4.1.1", | ||
@@ -22,3 +23,3 @@ "get-stack-trace": "^2.0.1", | ||
"pretty-hrtime": "^1.0.3", | ||
"roarr": "^2.12.0", | ||
"roarr": "^2.12.1", | ||
"serialize-error": "^3.0.0", | ||
@@ -38,3 +39,3 @@ "ulid": "^2.3.0" | ||
"coveralls": "^3.0.2", | ||
"eslint": "^5.11.0", | ||
"eslint": "^5.11.1", | ||
"eslint-config-canonical": "^15.0.1", | ||
@@ -44,5 +45,5 @@ "flow-bin": "^0.89.0", | ||
"gitdown": "^2.5.5", | ||
"husky": "^1.2.1", | ||
"husky": "^1.3.1", | ||
"nyc": "^13.1.0", | ||
"semantic-release": "^15.13.1", | ||
"semantic-release": "^15.13.2", | ||
"sinon": "^7.2.2" | ||
@@ -97,3 +98,3 @@ }, | ||
}, | ||
"version": "8.3.2" | ||
"version": "8.4.0" | ||
} |
@@ -21,2 +21,3 @@ <a name="slonik"></a> | ||
* Detail [logging](#slonik-debugging) | ||
* [Parsing and logging of the auto_explain logs.](#logging-auto_explain) | ||
* Built-in [asynchronous stack trace resolution](#log-stack-trace) | ||
@@ -40,2 +41,4 @@ * [Flow types](#types) | ||
* [`afterQuery`](#slonik-interceptors-afterquery) | ||
* [Recipes](#slonik-recipes) | ||
* [Logging `auto_explain`](#slonik-recipes-logging-auto_explain) | ||
* [Non-standard behaviour](#slonik-non-standard-behaviour) | ||
@@ -187,2 +190,85 @@ * [Conventions](#slonik-conventions) | ||
<a name="slonik-recipes"></a> | ||
## Recipes | ||
<a name="slonik-recipes-logging-auto_explain"></a> | ||
### Logging <code>auto_explain</code> | ||
`executionTime` log property describes how long it took for the client to execute the query, i.e. it includes the overhead of waiting for a connection and the network latency, among other things. However, it is possible to get the real query execution time by using [`auto_explain` module](https://www.postgresql.org/docs/current/auto-explain.html). | ||
There are several pre-requisites: | ||
```sql | ||
-- Load the extension. | ||
LOAD 'auto_explain'; | ||
-- or (if you are using AWS RDS): | ||
LOAD '$libdir/plugins/auto_explain'; | ||
-- Enable logging of all queries. | ||
SET auto_explain.log_analyze=true; | ||
SET auto_explain.log_format=json; | ||
SET auto_explain.log_min_duration=0; | ||
SET auto_explain.log_timing=true; | ||
-- Enables Slonik to capture auto_explain logs. | ||
SET client_min_messages=log; | ||
``` | ||
This can be configured using `onConnect` connection handler. | ||
```js | ||
const pool = await createPool('postgres://localhost', { | ||
onConnect: async (connection) => { | ||
await connection.query(sql`LOAD 'auto_explain'`); | ||
await connection.query(sql`SET auto_explain.log_analyze=true`); | ||
await connection.query(sql`SET auto_explain.log_format=json`); | ||
await connection.query(sql`SET auto_explain.log_min_duration=0`); | ||
await connection.query(sql`SET auto_explain.log_timing=true`); | ||
await connection.query(sql`SET client_min_messages=log`); | ||
} | ||
}); | ||
``` | ||
Slonik recognises and parses the `auto_explain` JSON message; Roarr logger will produce a pretty-print of the explain output, e.g. | ||
```yaml | ||
[2018-12-31T21:15:21.010Z] INFO (30) (@slonik): notice message | ||
notice: | ||
level: notice | ||
message: | ||
Query Text: SELECT count(*) FROM actor | ||
Plan: | ||
Node Type: Aggregate | ||
Strategy: Plain | ||
Partial Mode: Simple | ||
Parallel Aware: false | ||
Startup Cost: 4051.33 | ||
Total Cost: 4051.34 | ||
Plan Rows: 1 | ||
Plan Width: 8 | ||
Actual Startup Time: 26.791 | ||
Actual Total Time: 26.791 | ||
Actual Rows: 1 | ||
Actual Loops: 1 | ||
Plans: | ||
- | ||
Node Type: Seq Scan | ||
Parent Relationship: Outer | ||
Parallel Aware: false | ||
Relation Name: actor | ||
Alias: actor | ||
Startup Cost: 0 | ||
Total Cost: 3561.86 | ||
Plan Rows: 195786 | ||
Plan Width: 0 | ||
Actual Startup Time: 0.132 | ||
Actual Total Time: 15.29 | ||
Actual Rows: 195786 | ||
Actual Loops: 1 | ||
``` | ||
<a name="slonik-non-standard-behaviour"></a> | ||
@@ -189,0 +275,0 @@ ## Non-standard behaviour |
// @flow | ||
import { | ||
extractJson | ||
} from 'crack-json'; | ||
import isAutoExplainJsonMessage from './isAutoExplainJsonMessage'; | ||
export default (notice: Error) => { | ||
if (isAutoExplainJsonMessage(notice.message)) { | ||
return { | ||
level: notice.name, | ||
message: extractJson(notice.message)[0] | ||
}; | ||
} | ||
return { | ||
...JSON.parse(JSON.stringify(notice)), | ||
level: notice.name, | ||
message: notice.message | ||
}; | ||
}; |
@@ -7,2 +7,3 @@ // @flow | ||
export {default as formatNotice} from './formatNotice'; | ||
export {default as isAutoExplainJsonMessage} from './isAutoExplainJsonMessage'; | ||
export {default as mapTaggedTemplateLiteralInvocation} from './mapTaggedTemplateLiteralInvocation'; | ||
@@ -9,0 +10,0 @@ export {default as normalizeAnonymousValuePlaceholders} from './normalizeAnonymousValuePlaceholders'; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
238673
151
2618
837
12
+ Addedcrack-json@^1.1.0
+ Addedcrack-json@1.3.0(transitive)
Updatedroarr@^2.12.1