diff --git a/app/ProcessCpuProfiler.ts b/app/ProcessCpuProfiler.ts index 44ad6294fe30ae45544b93100d6ddc0de81e5988..42b9999269e7b6ca6c00098b213dfdcb9b1b6fc9 100644 --- a/app/ProcessCpuProfiler.ts +++ b/app/ProcessCpuProfiler.ts @@ -11,8 +11,6 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. -import {NewLogger} from "./lib/logger" - const SAMPLING_PERIOD = 150 // milliseconds const MAX_SAMPLES_DISTANCE = 20 * 1000000 // seconds @@ -30,13 +28,6 @@ export function getDurationInMicroSeconds(before:number) { return parseInt(String(getMicrosecondsTime() - before)) } -export async function profileFunc<T>(name:string, f: () => Promise<T>): Promise<T> { - const now = getMicrosecondsTime() - const res = await f() - NewLogger().trace('%s %sµs', name, getDurationInMicroSeconds(now)) - return res -} - interface CpuUsage { user: number system:number diff --git a/app/cli.ts b/app/cli.ts index 0060f3718be8a6d7f45749efa228847ec27076e0..33472bb2ac0cfea4e2b8eb955bb2fddb82b02a97 100644 --- a/app/cli.ts +++ b/app/cli.ts @@ -74,6 +74,7 @@ export const ExecuteCommand = () => { .option('--nohttplogs', 'Disable HTTP logs') .option('--isolate', 'Avoid the node to send peering or status informations to the network') .option('--forksize <size>', 'Maximum size of fork window', parseInt) + .option('--notrim', 'Disable the INDEX trimming.') .option('--memory', 'Memory mode') ; diff --git a/app/lib/blockchain/DuniterBlockchain.ts b/app/lib/blockchain/DuniterBlockchain.ts index 7298bdcb66872c3014c054d585c5c21bcf7adfc1..9b2c004ab8b117515b090868ac2a0a8082081e54 100644 --- a/app/lib/blockchain/DuniterBlockchain.ts +++ b/app/lib/blockchain/DuniterBlockchain.ts @@ -218,10 +218,7 @@ export class DuniterBlockchain { // Save indexes await dal.bindexDAL.insert(indexes.HEAD); - await dal.mindexDAL.insertBatch(indexes.mindex); - await dal.iindexDAL.insertBatch(indexes.iindex); - await dal.sindexDAL.insertBatch(indexes.sindex); - await dal.cindexDAL.insertBatch(indexes.cindex); + await dal.flushIndexes(indexes) // Create/Update nodes in wotb await this.updateMembers(block, dal); diff --git a/app/lib/common-libs/programOptions.ts b/app/lib/common-libs/programOptions.ts new file mode 100644 index 0000000000000000000000000000000000000000..0274130de70689cb1f9888631064246f184bc3c0 --- /dev/null +++ b/app/lib/common-libs/programOptions.ts @@ -0,0 +1,28 @@ +// Source file from duniter: Crypto-currency software to manage libre currency such as Ğ1 +// Copyright (C) 2018 Cedric Moreau <cem.moreau@gmail.com> +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. + +const opts = require('optimist').argv + +export interface ProgramOptions { + mdb?: string + home?: string + notrim?: boolean + syncTrace?: string +} + +export const cliprogram: ProgramOptions = { + mdb: opts.mdb, + home: opts.home, + notrim: opts.notrim, + syncTrace: opts['sync-trace'], +} diff --git a/app/lib/computation/QuickSync.ts b/app/lib/computation/QuickSync.ts index aa1e4791e064c9e810ef6c4a990ed97e9fa1ac6f..4993cbbe488f5b064615a5b86c2b2856408a783f 100644 --- a/app/lib/computation/QuickSync.ts +++ b/app/lib/computation/QuickSync.ts @@ -174,10 +174,12 @@ export class QuickSynchronizer { })) // Flush the INDEX (not bindex, which is particular) - await this.dal.mindexDAL.insertBatch(sync_mindex); - await this.dal.iindexDAL.insertBatch(sync_iindex); - await this.dal.sindexDAL.insertBatch(sync_sindex); - await this.dal.cindexDAL.insertBatch(sync_cindex); + await this.dal.flushIndexes({ + mindex: sync_mindex, + iindex: sync_iindex, + sindex: sync_sindex, + cindex: sync_cindex, + }) sync_iindex = local_iindex sync_cindex = local_cindex sync_mindex = local_mindex @@ -196,10 +198,12 @@ export class QuickSynchronizer { await DuniterBlockchain.updateWallets(sync_sindex, sync_memoryDAL) // Flush the INDEX again (needs to be done *before* the update of wotb links because of block#0) - await this.dal.iindexDAL.insertBatch(sync_iindex); - await this.dal.mindexDAL.insertBatch(sync_mindex); - await this.dal.sindexDAL.insertBatch(sync_sindex); - await this.dal.cindexDAL.insertBatch(sync_cindex); + await this.dal.flushIndexes({ + mindex: sync_mindex, + iindex: sync_iindex, + sindex: sync_sindex, + cindex: sync_cindex, + }) // --> Update links await this.dal.updateWotbLinks(local_cindex.concat(sync_cindex)); @@ -240,10 +244,12 @@ export class QuickSynchronizer { // Save the INDEX await this.dal.bindexDAL.insertBatch(sync_bindex); - await this.dal.mindexDAL.insertBatch(sync_mindex); - await this.dal.iindexDAL.insertBatch(sync_iindex); - await this.dal.sindexDAL.insertBatch(sync_sindex); - await this.dal.cindexDAL.insertBatch(sync_cindex); + await this.dal.flushIndexes({ + mindex: sync_mindex, + iindex: sync_iindex, + sindex: sync_sindex, + cindex: sync_cindex, + }) // Save the intermediary table of wallets const conditions = Underscore.keys(sync_memoryWallets) diff --git a/app/lib/dal/fileDAL.ts b/app/lib/dal/fileDAL.ts index b9e1cc9ef8139b94223ba92e920a621c38a439b4..256d93cbff504c377b2a15aae3d77bde615fdafb 100644 --- a/app/lib/dal/fileDAL.ts +++ b/app/lib/dal/fileDAL.ts @@ -28,6 +28,7 @@ import { FullSindexEntry, IindexEntry, IndexEntry, + MindexEntry, SindexEntry } from "../indexer" import {TransactionDTO} from "../dto/TransactionDTO" @@ -58,7 +59,6 @@ import {NewLogger} from "../logger" import {LokiBlockchain} from "./indexDAL/loki/LokiBlockchain" import {BlockchainDAO} from "./indexDAL/abstract/BlockchainDAO" import {LokiTransactions} from "./indexDAL/loki/LokiTransactions" -import {profileFunc} from "../../ProcessCpuProfiler" import {TxsDAO} from "./indexDAL/abstract/TxsDAO" import {LokiJsDriver} from "./drivers/LokiJsDriver" import {WalletDAO} from "./indexDAL/abstract/WalletDAO" @@ -73,6 +73,8 @@ import {CFSCore} from "./fileDALs/CFSCore" import {BlockchainArchiveDAO} from "./indexDAL/abstract/BlockchainArchiveDAO" import {Underscore} from "../common-libs/underscore" import {DBPeer} from "../db/DBPeer" +import {MonitorFlushedIndex} from "../debug/MonitorFlushedIndex" +import {cliprogram} from "../common-libs/programOptions" const readline = require('readline') const indexer = require('../indexer').Indexer @@ -87,6 +89,13 @@ export interface FileDALParams { wotb:WoTBInstance } +export interface IndexBatch { + mindex: MindexEntry[] + iindex: IindexEntry[] + sindex: SindexEntry[] + cindex: CindexEntry[] +} + export class FileDAL { rootPath:string @@ -987,12 +996,13 @@ export class FileDAL { } async trimIndexes(maxNumber:number) { - await profileFunc('[loki][bindex][trim]', () => this.bindexDAL.trimBlocks(maxNumber)) - await profileFunc('[loki][iindex][trim]', () => this.iindexDAL.trimRecords(maxNumber)) - await profileFunc('[loki][mindex][trim]', () => this.mindexDAL.trimRecords(maxNumber)) - await profileFunc('[loki][cindex][trim]', () => this.cindexDAL.trimExpiredCerts(maxNumber)) - await profileFunc('[loki][sindex][trim]', () => this.sindexDAL.trimConsumedSource(maxNumber)) - return true; + if (!cliprogram.notrim) { + await this.bindexDAL.trimBlocks(maxNumber) + await this.iindexDAL.trimRecords(maxNumber) + await this.mindexDAL.trimRecords(maxNumber) + await this.cindexDAL.trimExpiredCerts(maxNumber) + await this.sindexDAL.trimConsumedSource(maxNumber) + } } async trimSandboxes(block:{ medianTime: number }) { @@ -1261,4 +1271,12 @@ export class FileDAL { } return members } + + @MonitorFlushedIndex() + async flushIndexes(indexes: IndexBatch) { + await this.mindexDAL.insertBatch(indexes.mindex) + await this.iindexDAL.insertBatch(indexes.iindex) + await this.sindexDAL.insertBatch(indexes.sindex) + await this.cindexDAL.insertBatch(indexes.cindex) + } } diff --git a/app/lib/dal/indexDAL/loki/LokiBIndex.ts b/app/lib/dal/indexDAL/loki/LokiBIndex.ts index 59aa3c87dd961f0b7c37a75b764b80bfe8930ddd..912cf11bc2acf14d32e4eee638ff8bae3674329f 100644 --- a/app/lib/dal/indexDAL/loki/LokiBIndex.ts +++ b/app/lib/dal/indexDAL/loki/LokiBIndex.ts @@ -3,6 +3,7 @@ import {DBHead} from "../../../db/DBHead" import {BIndexDAO} from "../abstract/BIndexDAO" import {NewLogger} from "../../../logger" import {getDurationInMicroSeconds, getMicrosecondsTime} from "../../../../ProcessCpuProfiler" +import {MonitorLokiExecutionTime} from "../../../debug/MonitorLokiExecutionTime" const logger = NewLogger() @@ -75,6 +76,7 @@ export class LokiBIndex extends LokiIndex<DBHead> implements BIndexDAO { .find({ number: HEAD.number - nbHEADs + 1 })[0] } + @MonitorLokiExecutionTime(true) async trimBlocks(maxnumber: number): Promise<void> { this.collection .chain() diff --git a/app/lib/dal/indexDAL/loki/LokiBlockchain.ts b/app/lib/dal/indexDAL/loki/LokiBlockchain.ts index 245b42ec01305af4e7dab763513e06adedd31b30..4a15363550a99391c22b312fdac60f41d51daadf 100644 --- a/app/lib/dal/indexDAL/loki/LokiBlockchain.ts +++ b/app/lib/dal/indexDAL/loki/LokiBlockchain.ts @@ -1,10 +1,7 @@ import {LokiIndex} from "./LokiIndex" -import {NewLogger} from "../../../logger" import {BlockchainDAO} from "../abstract/BlockchainDAO" import {DBBlock} from "../../../db/DBBlock" -import {getMicrosecondsTime} from "../../../../ProcessCpuProfiler" - -const logger = NewLogger() +import {MonitorLokiExecutionTime} from "../../../debug/MonitorLokiExecutionTime" export class LokiBlockchain extends LokiIndex<DBBlock> implements BlockchainDAO { @@ -35,17 +32,15 @@ export class LokiBlockchain extends LokiIndex<DBBlock> implements BlockchainDAO } } + @MonitorLokiExecutionTime(true) async getBlock(number:string | number) { - const now = getMicrosecondsTime() - const b = this.collection + return this.collection .chain() .find({ number: parseInt(String(number)), fork: false }) .data()[0] - logger.trace('[loki][%s][getBlock] %sµs', this.collectionName, (getMicrosecondsTime() - now), number) - return b } async getPotentialRoots() { diff --git a/app/lib/dal/indexDAL/loki/LokiCIndex.ts b/app/lib/dal/indexDAL/loki/LokiCIndex.ts index 789ac77df3dd44d76be3a6d011ea5455bc3d31d8..81cc750b20e467240e62fb8606b490187090d95b 100644 --- a/app/lib/dal/indexDAL/loki/LokiCIndex.ts +++ b/app/lib/dal/indexDAL/loki/LokiCIndex.ts @@ -2,6 +2,7 @@ import {CIndexDAO} from "../abstract/CIndexDAO" import {LokiIndex} from "./LokiIndex" import {CindexEntry, FullCindexEntry, Indexer} from "../../../indexer" import {CommonConstants} from "../../../common-libs/constants" +import {MonitorLokiExecutionTime} from "../../../debug/MonitorLokiExecutionTime" export class LokiCIndex extends LokiIndex<CindexEntry> implements CIndexDAO { @@ -118,6 +119,7 @@ export class LokiCIndex extends LokiIndex<CindexEntry> implements CIndexDAO { .filter(r => this.collection.find({ issuer: r.issuer, receiver: r.receiver, created_on: r.created_on, expired_on: { $gt: 0 } }).length === 0) } + @MonitorLokiExecutionTime(true) async trimExpiredCerts(belowNumber: number): Promise<void> { const expired = this.collection.find({ $and: [ diff --git a/app/lib/dal/indexDAL/loki/LokiIIndex.ts b/app/lib/dal/indexDAL/loki/LokiIIndex.ts index 8124c1bdbb0d2fbdbb6d2007e5903115dcfba734..d0fc9cfdc315b6a31171ef677fa41d617d5f4ef6 100644 --- a/app/lib/dal/indexDAL/loki/LokiIIndex.ts +++ b/app/lib/dal/indexDAL/loki/LokiIIndex.ts @@ -1,9 +1,8 @@ import {FullIindexEntry, IindexEntry, Indexer} from "../../../indexer" import {IIndexDAO} from "../abstract/IIndexDAO" import {LokiPubkeySharingIndex} from "./LokiPubkeySharingIndex" -import {getDurationInMicroSeconds, getMicrosecondsTime} from "../../../../ProcessCpuProfiler" -import {NewLogger} from "../../../logger" import {OldIindexEntry} from "../../../db/OldIindexEntry" +import {MonitorLokiExecutionTime} from "../../../debug/MonitorLokiExecutionTime" export class LokiIIndex extends LokiPubkeySharingIndex<IindexEntry> implements IIndexDAO { @@ -130,11 +129,9 @@ export class LokiIIndex extends LokiPubkeySharingIndex<IindexEntry> implements I ) as Promise<FullIindexEntry|null> } + @MonitorLokiExecutionTime() async getMembersPubkeys(): Promise<{ pub: string }[]> { - const now = getMicrosecondsTime() - const res = (await this.getMembers()).map(m => ({ pub: m.pubkey })) - NewLogger().trace('[getMembersPubkeys] %sµs', getDurationInMicroSeconds(now)) - return res + return (await this.getMembers()).map(m => ({ pub: m.pubkey })) } async getToBeKickedPubkeys(): Promise<string[]> { diff --git a/app/lib/dal/indexDAL/loki/LokiIndex.ts b/app/lib/dal/indexDAL/loki/LokiIndex.ts index 6283a831244c629ed2057cf9e28589e064a51279..e4551fb26f2e466d4f839be5eb4b7f9ec469120b 100644 --- a/app/lib/dal/indexDAL/loki/LokiIndex.ts +++ b/app/lib/dal/indexDAL/loki/LokiIndex.ts @@ -1,9 +1,6 @@ import {GenericDAO} from "../abstract/GenericDAO" -import {NewLogger} from "../../../logger" -import {getMicrosecondsTime} from "../../../../ProcessCpuProfiler" import {LokiCollectionManager} from "./LokiCollectionManager" - -const logger = NewLogger() +import {MonitorLokiExecutionTime} from "../../../debug/MonitorLokiExecutionTime" export interface IndexData { written_on: string @@ -16,48 +13,37 @@ export abstract class LokiIndex<T extends IndexData> extends LokiCollectionManag } async insert(record: T): Promise<void> { - const now = getMicrosecondsTime() this.collection.insert(record) - // logger.trace('[loki][%s][insert] %sµs', this.collectionName, (getMicrosecondsTime() - now)) } + @MonitorLokiExecutionTime(true) async findRaw(criterion?:any) { - const now = getMicrosecondsTime() - const res = this.collection.find(criterion) - logger.trace('[loki][%s][findRaw] => %sµs', this.collectionName, (getMicrosecondsTime() - now), criterion) - return res + return this.collection.find(criterion) } + @MonitorLokiExecutionTime(true) async findRawWithOrder(criterion:any, sort:((string|((string|boolean)[]))[])) { - const now = getMicrosecondsTime() const res = this.collection .chain() .find(criterion) .compoundsort(sort) - logger.trace('[loki][%s][findRaw] => %sµs', this.collectionName, (getMicrosecondsTime() - now), criterion) return res.data() } + @MonitorLokiExecutionTime() async insertBatch(records: T[]): Promise<void> { - const now = getMicrosecondsTime() records.map(r => this.insert(r)) - if (records.length) { - logger.trace('[loki][%s][insertBatch] %s record(s) in %sµs', this.collectionName, records.length, getMicrosecondsTime() - now) - } } + @MonitorLokiExecutionTime(true) async getWrittenOn(blockstamp: string): Promise<T[]> { - const now = getMicrosecondsTime() const criterion:any = { writtenOn: parseInt(blockstamp) } - const res = this.collection.find(criterion) - logger.trace('[loki][%s][getWrittenOn] %sµs', this.collectionName, (getMicrosecondsTime() - now), blockstamp) - return res + return this.collection.find(criterion) } + @MonitorLokiExecutionTime(true) async removeBlock(blockstamp: string): Promise<void> { - const now = getMicrosecondsTime() const data = await this.getWrittenOn(blockstamp) data.map(d => this.collection.remove(d)) - logger.trace('[loki][%s][removeBlock] %sµs', this.collectionName, (getMicrosecondsTime() - now), blockstamp) } } diff --git a/app/lib/dal/indexDAL/loki/LokiPubkeySharingIndex.ts b/app/lib/dal/indexDAL/loki/LokiPubkeySharingIndex.ts index 36236c07fda6d0db7b23fcea0d9916c03d6fc940..e44ee62f2b98926ebed828a83c0f874cf7da8751 100644 --- a/app/lib/dal/indexDAL/loki/LokiPubkeySharingIndex.ts +++ b/app/lib/dal/indexDAL/loki/LokiPubkeySharingIndex.ts @@ -1,8 +1,10 @@ import {Indexer} from "../../../indexer" import {LokiIndex} from "./LokiIndex" +import {MonitorLokiExecutionTime} from "../../../debug/MonitorLokiExecutionTime" export class LokiPubkeySharingIndex<T extends { written_on:string, writtenOn:number, pub:string }> extends LokiIndex<T> { + @MonitorLokiExecutionTime(true) async trimRecords(belowNumber: number): Promise<void> { // TODO: may be optimized by only selecting new offseted records const criterion:any = { diff --git a/app/lib/dal/indexDAL/loki/LokiSIndex.ts b/app/lib/dal/indexDAL/loki/LokiSIndex.ts index 575d529a418fd59fcc1579c3bacc30f6d204fe02..deb8d693dab897c7dbe1b8f9698fb6ce46f09d0c 100644 --- a/app/lib/dal/indexDAL/loki/LokiSIndex.ts +++ b/app/lib/dal/indexDAL/loki/LokiSIndex.ts @@ -2,6 +2,7 @@ import {LokiIndex} from "./LokiIndex" import {FullSindexEntry, Indexer, SindexEntry} from "../../../indexer" import {SIndexDAO} from "../abstract/SIndexDAO" import {Underscore} from "../../../common-libs/underscore" +import {MonitorLokiExecutionTime} from "../../../debug/MonitorLokiExecutionTime" export class LokiSIndex extends LokiIndex<SindexEntry> implements SIndexDAO { @@ -82,6 +83,7 @@ export class LokiSIndex extends LokiIndex<SindexEntry> implements SIndexDAO { return Indexer.DUP_HELPERS.reduceBy(reducables, ['identifier', 'pos']) } + @MonitorLokiExecutionTime(true) async trimConsumedSource(belowNumber: number): Promise<void> { const consumed = this.collection .find({ writtenOn: { $lt: belowNumber }}) diff --git a/app/lib/dal/sqliteDAL/AbstractSQLite.ts b/app/lib/dal/sqliteDAL/AbstractSQLite.ts index 7e3c42b70b1724c60e0ff3a6aa7f92031ddf5a8f..4a2d0ec59dc185beb2647d20d422f9f6178ad586 100644 --- a/app/lib/dal/sqliteDAL/AbstractSQLite.ts +++ b/app/lib/dal/sqliteDAL/AbstractSQLite.ts @@ -15,13 +15,10 @@ import {SQLiteDriver} from "../drivers/SQLiteDriver" import {Initiable} from "./Initiable" import {getDurationInMicroSeconds, getMicrosecondsTime} from "../../../ProcessCpuProfiler" import {Underscore} from "../../common-libs/underscore" +import {NewLogger} from "../../logger" +import {MonitorSQLExecutionTime} from "../../debug/MonitorSQLExecutionTime" -/** - * Created by cgeek on 22/08/15. - */ - -const colors = require('colors'); -const logger = require('../../logger').NewLogger('sqlite'); +const logger = NewLogger('sqlite') export interface BeforeSaveHook<T> { (t:T): void @@ -43,26 +40,11 @@ export abstract class AbstractSQLite<T> extends Initiable { super() } + @MonitorSQLExecutionTime() async query(sql:string, params: any[] = []): Promise<T[]> { try { - const start = getMicrosecondsTime() const res = await this.driver.executeAll(sql, params || []); - const duration = getDurationInMicroSeconds(start) - logger.trace('[sqlite][query] %s %s %sµs', sql, JSON.stringify(params || []), duration) - const entities = res.map((t:T) => this.toEntity(t)) - // Display result - let msg = sql + ' | %s\t==> %s rows in %s ms'; - if (duration <= 2) { - msg = colors.green(msg); - } else if(duration <= 5) { - msg = colors.yellow(msg); - } else if (duration <= 10) { - msg = colors.magenta(msg); - } else if (duration <= 100) { - msg = colors.red(msg); - } - logger.query(msg, JSON.stringify(params || []), entities.length, duration); - return entities; + return res.map((t:T) => this.toEntity(t)) } catch (e) { logger.error('ERROR >> %s', sql, JSON.stringify(params || []), e.stack || e.message || e); throw e; diff --git a/app/lib/debug/MonitorFlushedIndex.ts b/app/lib/debug/MonitorFlushedIndex.ts new file mode 100644 index 0000000000000000000000000000000000000000..f2d083ccef8a0488a4f4cce955fe77cd6cf92072 --- /dev/null +++ b/app/lib/debug/MonitorFlushedIndex.ts @@ -0,0 +1,52 @@ +// Source file from duniter: Crypto-currency software to manage libre currency such as Ğ1 +// Copyright (C) 2018 Cedric Moreau <cem.moreau@gmail.com> +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. + +import {cliprogram} from "../common-libs/programOptions" +import {IndexBatch} from "../dal/fileDAL" + +export const MonitorFlushedIndex = function () { + return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) { + const original = descriptor.value + if (original.__proto__.constructor.name === "AsyncFunction") { + descriptor.value = async function (...args:any[]) { + const pub = cliprogram.syncTrace + if (pub) { + const batch: IndexBatch = args[0] + batch.iindex.forEach(e => { + if (e.pub === pub) { + console.log(JSON.stringify(e)) + } + }) + batch.mindex.forEach(e => { + if (e.pub === pub) { + console.log(JSON.stringify(e)) + } + }) + batch.cindex.forEach(e => { + if (e.issuer === pub || e.receiver === pub) { + console.log(JSON.stringify(e)) + } + }) + batch.sindex.forEach(e => { + if (e.conditions.indexOf(pub || '') !== -1) { + console.log(JSON.stringify(e)) + } + }) + } + return await original.apply(this, args) + } + } else { + throw Error("Monitoring a synchronous function is not allowed.") + } + } +} \ No newline at end of file diff --git a/app/lib/debug/MonitorLokiExecutionTime.ts b/app/lib/debug/MonitorLokiExecutionTime.ts new file mode 100644 index 0000000000000000000000000000000000000000..ca4f154125275d371848ca5e2c0403dcd965861c --- /dev/null +++ b/app/lib/debug/MonitorLokiExecutionTime.ts @@ -0,0 +1,38 @@ +// Source file from duniter: Crypto-currency software to manage libre currency such as Ğ1 +// Copyright (C) 2018 Cedric Moreau <cem.moreau@gmail.com> +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. + +import {NewLogger} from "../logger" +import {getMicrosecondsTime} from "../../ProcessCpuProfiler" + +const theLogger = NewLogger() + +export const MonitorLokiExecutionTime = function (dumpFirstParam = false) { + return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) { + const original = descriptor.value + if (original.__proto__.constructor.name === "AsyncFunction") { + descriptor.value = async function (...args:any[]) { + const that :any = this + const now = getMicrosecondsTime() + const result = await original.apply(this, args) + if (dumpFirstParam) { + theLogger.trace('[loki][%s][%s] => %sµs', that.collectionName, propertyKey, (getMicrosecondsTime() - now), args && args[0]) + } else { + theLogger.trace('[loki][%s][%s] => %sµs', that.collectionName, propertyKey, (getMicrosecondsTime() - now)) + } + return result + } + } else { + throw Error("Monitoring a Loki synchronous function is not allowed.") + } + } +} \ No newline at end of file diff --git a/app/lib/debug/MonitorSQLExecutionTime.ts b/app/lib/debug/MonitorSQLExecutionTime.ts new file mode 100644 index 0000000000000000000000000000000000000000..3f2dff3668f1b19365bddc94d48415ad9bae7278 --- /dev/null +++ b/app/lib/debug/MonitorSQLExecutionTime.ts @@ -0,0 +1,36 @@ +// Source file from duniter: Crypto-currency software to manage libre currency such as Ğ1 +// Copyright (C) 2018 Cedric Moreau <cem.moreau@gmail.com> +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. + +import {getDurationInMicroSeconds, getMicrosecondsTime} from "../../ProcessCpuProfiler" +import {NewLogger} from "../logger" + +const theLogger = NewLogger() + +export const MonitorSQLExecutionTime = function () { + return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) { + const original = descriptor.value + if (original.__proto__.constructor.name === "AsyncFunction") { + descriptor.value = async function (...args:any[]) { + const start = getMicrosecondsTime() + const sql: string = args[0] + const params: any[] = args[1] + const entities: any[] = await original.apply(this, args) + const duration = getDurationInMicroSeconds(start) + theLogger.trace('[sqlite][query] %s %s %sµs', sql, JSON.stringify(params || []), duration) + return entities + } + } else { + throw Error("Monitoring an SQL synchronous function is not allowed.") + } + } +} \ No newline at end of file