Skip to content
Permalink
Browse files
[CONJS-167] Custom logging implementation
  • Loading branch information
rusher committed Jun 8, 2021
1 parent d176b01 commit a8d9e7e
Show file tree
Hide file tree
Showing 29 changed files with 552 additions and 583 deletions.
@@ -28,8 +28,7 @@
| **insertIdAsNumber** | Whether the query should return last insert id from INSERT/UPDATE command as BigInt or Number. default return BigInt |*boolean* | false |
| **decimalAsNumber** | Whether the query should return decimal as Number. If enable, this might return approximate values. |*boolean* | false |
| **bigIntAsNumber** | Whether the query should return BigInt data type as Number. If enable, this might return approximate values. |*boolean* | false |
| **restrictedAuth** | if set, restrict authentication plugin to secure list. Default provided plugins are mysql_native_password, mysql_clear_password, client_ed25519, dialog, sha256_password and caching_sha2_password |*Array|String* | |

| **logger** | Configure logger. For more information, see the [`logger` option](#logger) documentation. |*mixed*|

### JSON or String configuration

@@ -56,6 +55,45 @@ mariadb.createConnection({
//passing argument as String
mariadb.createConnection('mariadb://root:pass@localhost:3307/db?metaAsArray=false&ssl=true&dateStrings=true');
```
## logger

Driver permit mapping the logs to an external logger.
There is 3 caller functions:
* network(string): called for each network exchanges.
* query(string): called for each commands
* error(Error): called for each error.

if setting one function, function will be used for all loggers.
(ie. logger: console.log === logger: { network: console.log, query: console.log, error: console.log})

**Example:**

```javascript
const mariadb = require('mariadb');
const winston = require('winston');
const logger = winston.createLogger({
level: 'info',
transports: [
// - Write all logs with level `error` and below to `error.log`
// - Write all logs with level `info` and below to `combined.log`
new winston.transports.Console({ filename: 'error.log', level: 'error' }),
new winston.transports.Console({ filename: 'combined.log' })
]
});
const pool = mariadb.createPool({
host: 'mydb.com',
user:'myUser',
password: 'myPwd',
logger: {
network: (msg) => logger.silly(msg),
query: (msg) => logger.info(msg),
error: (err) => logger.error(err),
}
});
```



## SSL
@@ -350,12 +388,12 @@ mariadb.createConnection({
| **rsaPublicKey** | Indicate path/content to MySQL server RSA public key. use requires Node.js v11.6+ |*string* | |
| **cachingRsaPublicKey** | Indicate path/content to MySQL server caching RSA public key. use requires Node.js v11.6+ |*string* | |
| **allowPublicKeyRetrieval** | Indicate that if `rsaPublicKey` or `cachingRsaPublicKey` public key are not provided, if client can ask server to send public key. |*boolean* | false |
| **supportBigInt** | Whether resultset should return javascript ES2020 [BigInt](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt) for [BIGINT](https://mariadb.com/kb/en/bigint/) data type. This ensures having expected value even for value > 2^53 (see [safe](#big-integer-support) range). |*boolean* | false |
| **restrictedAuth** | if set, restrict authentication plugin to secure list. Default provided plugins are mysql_native_password, mysql_clear_password, client_ed25519, dialog, sha256_password and caching_sha2_password |*Array|String* | |


## F.A.Q.

#### error Hostname/IP doesn't match certificate's altnames
#### error Hostname/IP doesn't match certificate's alt-names

Clients verify certificate SAN (subject alternative names) and CN to ensure that the certificate corresponds to the hostname. If the certificate's SAN/CN does not correspond to the `host` option, it returns an error such as:

@@ -160,13 +160,6 @@ DB_PWD=secretPasswrd
```
.env files must NOT be pushed into repository, using .gitignore

### Default options consideration

For new project, enabling option `supportBigInt` is recommended (It will be in a future 3.x version).

This option permits to avoid exact value for big integer (value > 2^53) (see [javascript ES2020
BigInt](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt) )

# Promise API

**Base:**
@@ -272,6 +265,7 @@ Essential options list:
| **`socketTimeout`** | Sets the socket timeout in milliseconds after connection succeeds. A value of `0` disables the timeout. |*integer* | 0|
| **`queryTimeout`** | Set maximum query time in ms (an error will be thrown if limit is reached). 0 or undefined meaning no timeout. This can be superseded for a query using [`timeout`](https://github.com/mariadb-corporation/mariadb-connector-nodejs/blob/master/documentation/promise-api.md#timeout) option|*int* |0|
| **`rowsAsArray`** | Returns result-sets as arrays, rather than JSON. This is a faster way to get results. For more information, see Query. |*boolean* | false|
| **`logger`** | Configure logger. For more information, see the [`logger` option](/documentation/connection-options.md#logger) documentation. |*mixed*|

For more information, see the [Connection Options](/documentation/connection-options.md) documentation.

@@ -67,7 +67,7 @@ class BatchBulk extends Parser {

if (!this.validateParameters(info)) return;

this.sendComStmtBulkExecute(out, info);
this.sendComStmtBulkExecute(out, opts, info);
}

/**
@@ -218,10 +218,15 @@ class BatchBulk extends Parser {

/**
* Send a COM_STMT_BULK_EXECUTE
* @param out
* @param info
* @param out output packet writer
* @param ops options
* @param info information
*/
sendComStmtBulkExecute(out, info) {
sendComStmtBulkExecute(out, opts, info) {
if (opts.logger.query)
opts.logger.query(
`BULK: (${this.prepare.id}) ${opts.logger.logParam ? this.displaySql() : this.sql}`
);
const parameterCount = this.prepare.parameters.length;
this.rowIdx = 0;
this.vals = this.values[this.rowIdx++];
@@ -18,6 +18,7 @@ class ChangeUser extends Handshake {
}

start(out, opts, info) {
if (opts.logger.query) opts.logger.query(`CHANGE USER to '${this.opts.user || ''}'`);
this.configAssign(opts, this.opts);
let authToken;
const pwd = Array.isArray(this.opts.password) ? this.opts.password[0] : this.opts.password;
@@ -7,15 +7,17 @@ const Command = require('./command');
* see https://mariadb.com/kb/en/3-binary-protocol-prepared-statements-com_stmt_close/
*/
class ClosePrepare extends Command {
constructor(resolve, reject, statementId) {
constructor(resolve, reject, prepare) {
super(resolve, reject);
this.statementId = statementId;
this.prepare = prepare;
}

start(out, opts, info) {
if (opts.logger.query)
opts.logger.query(`CLOSE PREPARE: (${this.prepare.id}) ${this.prepare.query}`);
out.startPacket(this);
out.writeInt8(0x19);
out.writeInt32(this.statementId);
out.writeInt32(this.prepare.id);
out.flush();
this.onPacketReceive = null;
this.emit('send_end');
@@ -56,16 +56,24 @@ class Command extends EventEmitter {
* @param errno error number
*/
throwNewError(msg, fatal, info, sqlState, errno) {
const err = Errors.createError(
msg,
this.displaySql(),
fatal,
info,
sqlState,
errno,
this.stack,
false
);
this.onPacketReceive = null;
if (this.reject) {
process.nextTick(
this.reject,
Errors.createError(msg, this.displaySql(), fatal, info, sqlState, errno, this.stack, false)
);
process.nextTick(this.reject, err);
this.resolve = null;
this.reject = null;
}
this.emit('end');
return err;
}

/**
@@ -58,6 +58,10 @@ class Execute extends Parser {
typeof value.read === 'function') ||
Buffer.isBuffer(value))
) {
if (opts.logger.query)
opts.logger.query(
`EXECUTE: (${this.prepare.id}) ${opts.logger.logParam ? this.displaySql() : this.sql}`
);
if (!this.longDataStep) {
this.longDataStep = true;
this.registerStreamSendEvent(out, info);
@@ -70,6 +74,10 @@ class Execute extends Parser {

if (!this.longDataStep) {
// no stream parameter, so can send directly
if (opts.logger.query)
opts.logger.query(
`EXECUTE: (${this.prepare.id}) ${opts.logger.logParam ? this.displaySql() : this.sql}`
);
this.sendComStmtExecute(out, info);
}
}
@@ -13,6 +13,7 @@ class Ping extends Command {
}

start(out, opts, info) {
if (opts.logger.query) opts.logger.query('PING');
this.onPacketReceive = this.readPingResponsePacket;
out.startPacket(this);
out.writeInt8(0x0e);
@@ -25,6 +25,7 @@ class Prepare extends Parser {
* @param info connection information
*/
start(out, opts, info) {
if (opts.logger.query) opts.logger.query(`PREPARE: ${this.sql}`);
this.onPacketReceive = this.readPrepareResultPacket;
// check in cache if enabled
if (info._prepareCache) {
@@ -28,6 +28,8 @@ class Query extends Parser {
* @param info connection information
*/
start(out, opts, info) {
if (opts.logger.query)
opts.logger.query(`QUERY: ${opts.logger.logParam ? this.displaySql() : this.sql}`);
this.onPacketReceive = this.readResponsePacket;
if (!this.initialValues) {
//shortcut if no parameters
@@ -12,6 +12,7 @@ class Quit extends Command {
}

start(out, opts, info) {
if (opts.logger.query) opts.logger.query(`QUIT`);
this.onPacketReceive = this.skipResults;
out.startPacket(this);
out.writeInt8(0x01);
@@ -13,6 +13,7 @@ class Reset extends Command {
}

start(out, opts, info) {
if (opts.logger.query) opts.logger.query(`RESET`);
this.onPacketReceive = this.readResetResponsePacket;
out.startPacket(this);
out.writeInt8(0x1f);
@@ -83,7 +83,34 @@ class ConnectionOptions {
this.debug = opts.debug || false;
this.debugCompress = opts.debugCompress || false;
this.debugLen = opts.debugLen || 256;
this.logPackets = opts.logPackets || false;

if (opts.logger) {
if (typeof opts.logger === 'function') {
this.logger = {
network: opts.logger,
query: opts.logger,
error: opts.logger,
logParam: true
};
} else {
this.logger = {
network: opts.logger.network,
query: opts.logger.query,
error: opts.logger.error,
logParam:
opts.logger.logParam == null || opts.logger.logParam == undefined
? true
: opts.logger.logParam
};
}
} else {
this.logger = { network: null, query: null, error: null, logParam: false };
if ((this.debug || this.debugCompress) && !this.logger.network) {
this.logger.network = console.log;
}
}
this.debug = this.logger.network ? true : false;

this.trace = opts.trace || false;

// result-set
@@ -185,7 +212,6 @@ class ConnectionOptions {
if (opts.bulk) opts.bulk = opts.bulk == 'true';
if (opts.rsaPublicKey) opts.rsaPublicKey = opts.rsaPublicKey;
if (opts.cachingRsaPublicKey) opts.cachingRsaPublicKey = opts.cachingRsaPublicKey;
if (opts.logPackets) opts.logPackets = opts.logPackets == 'true';
if (opts.allowPublicKeyRetrieval)
opts.allowPublicKeyRetrieval = opts.allowPublicKeyRetrieval == 'true';

0 comments on commit a8d9e7e

Please sign in to comment.