Skip to content

Commit 2ce877f

Browse files
author
Julien Heller
authored
Merge pull request #75 from EOSIO/debug-logging
Debug logging
2 parents b41fc71 + 46227bb commit 2ce877f

File tree

3 files changed

+70
-20
lines changed

3 files changed

+70
-20
lines changed

src/MassiveActionHandler.ts

Lines changed: 42 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -64,34 +64,48 @@ export class MassiveActionHandler extends AbstractActionHandler {
6464
* throw an error.
6565
*
6666
* @param sequenceName The name of the MigrationSequence to be run.
67+
* @param pgp pg-promise instance
68+
* @param initial True if this is the first migration
6769
*/
6870
public async migrate(
6971
sequenceName: string,
7072
pgp: IDatabase<{}> = this.massiveInstance.instance,
7173
initial: boolean = false,
7274
): Promise<void> {
75+
this.log.info(`Migrating database with Migration Sequence '${sequenceName}'...`)
76+
const migrateStart = Date.now()
7377
const migrationSequence = this.migrationSequenceByName[sequenceName]
7478
if (!migrationSequence) {
7579
throw new NonExistentMigrationError(sequenceName)
7680
}
7781
let ranMigrations: Migration[] = []
7882
if (!initial) {
79-
ranMigrations = await this.loadRanMigrations()
83+
ranMigrations = await this.loadAppliedMigrations()
8084
}
8185
const extendedMigrations = ranMigrations.concat(migrationSequence.migrations)
82-
const migrationRunner = new MigrationRunner(this.massiveInstance.instance, extendedMigrations, this.dbSchema, true)
86+
const migrationRunner = new MigrationRunner(
87+
this.massiveInstance.instance,
88+
extendedMigrations,
89+
this.dbSchema,
90+
this.log,
91+
true
92+
)
8393
await migrationRunner.migrate(
8494
migrationSequence.sequenceName,
8595
this.lastProcessedBlockNumber + 1,
8696
pgp,
8797
initial,
8898
)
8999
await this.massiveInstance.reload()
100+
const migrateTime = Date.now() - migrateStart
101+
this.log.info(`Migrated database with Migration Sequence ${sequenceName} (${migrateTime}ms)`)
90102
}
91103

92104
/**
93105
* Sets up the database by idempotently creating the schema, installing CyanAudit, creates internally used tables, and
94106
* runs any initial migration sequences provided.
107+
*
108+
* @param initSequenceName The name of the MigrationSequence to be used to migrate the database initially
95109
*/
96110
protected async setup(initSequenceName: string = 'init'): Promise<void> {
97111
if (this.initialized) {
@@ -100,15 +114,15 @@ export class MassiveActionHandler extends AbstractActionHandler {
100114

101115
if (!this.migrationSequenceByName[initSequenceName]) {
102116
if (initSequenceName === 'init') {
103-
this.log.warn(`No 'init' Migration sequence was provided, nor was a different initSequenceName.` +
104-
'No initial migrations have been run.')
117+
this.log.warn(`No 'init' Migration sequence was provided, nor was a different initSequenceName. ` +
118+
'No initial migrations have been run.')
105119
} else {
106120
throw new NonExistentMigrationError(initSequenceName)
107121
}
108122
}
109123

110124
try {
111-
const migrationRunner = new MigrationRunner(this.massiveInstance.instance, [], this.dbSchema)
125+
const migrationRunner = new MigrationRunner(this.massiveInstance.instance, [], this.dbSchema, this.log)
112126
await migrationRunner.setup()
113127
await this.massiveInstance.reload()
114128
await this.migrate(initSequenceName, this.massiveInstance.instance, true)
@@ -126,16 +140,12 @@ export class MassiveActionHandler extends AbstractActionHandler {
126140
}
127141

128142
protected async handleWithState(handle: (state: any, context?: any) => void): Promise<void> {
129-
const indexState = await this.loadIndexState()
130-
const { lastIrreversibleBlockNumber, blockNumber } = indexState
131-
if (blockNumber < lastIrreversibleBlockNumber) {
143+
if (this.lastProcessedBlockNumber < this.lastIrreversibleBlockNumber) {
132144
await this.turnOffCyanAudit()
133-
const db = this.schemaInstance
134-
await handle(db)
135145
} else {
136146
await this.turnOnCyanAudit()
137-
await this.handleBlockWithTransactionId(handle)
138147
}
148+
await this.handleBlockWithTransactionId(handle)
139149
}
140150

141151
protected async updateIndexState(
@@ -182,7 +192,9 @@ export class MassiveActionHandler extends AbstractActionHandler {
182192
}
183193
}
184194

185-
protected async loadRanMigrations(): Promise<Migration[]> {
195+
protected async loadAppliedMigrations(): Promise<Migration[]> {
196+
this.log.debug('Loading applied run migrations...')
197+
const loadStart = Date.now()
186198
const processedMigrationRows = await this.massiveInstance._migration.find()
187199
const processedMigrations = processedMigrationRows.map((row: any) => {
188200
return {
@@ -198,8 +210,11 @@ export class MassiveActionHandler extends AbstractActionHandler {
198210
if (expectedName !== actualName) {
199211
throw new MismatchedMigrationsError(expectedName, actualName, index)
200212
}
213+
this.log.debug(`Previously applied migration name and index matches expected: ${index} -- ${expectedName}`)
201214
ranMigrations.push(this.allMigrations[index])
202215
}
216+
const loadTime = Date.now() - loadStart
217+
this.log.debug(`Loaded ${ranMigrations.length} previously applied migrations (${loadTime}ms)`)
203218
return ranMigrations
204219
}
205220

@@ -215,10 +230,9 @@ export class MassiveActionHandler extends AbstractActionHandler {
215230
},
216231
)
217232
for (const { block_number: rollbackNumber, txid } of blockNumberTxIds) {
218-
this.log.info(`ROLLING BACK BLOCK ${rollbackNumber}`)
233+
this.log.debug(`Rolling back block ${rollbackNumber} (undoing database transaction ${txid})...`)
219234
await this.massiveInstance.cyanaudit.fn_undo_transaction(txid)
220235
}
221-
this.log.info(`Rollback complete!`)
222236
}
223237

224238
private warnOverwrite(db: any, toOverwrite: string): void {
@@ -231,11 +245,14 @@ export class MassiveActionHandler extends AbstractActionHandler {
231245
private async turnOnCyanAudit(): Promise<void> {
232246
if (!this.cyanauditEnabled) {
233247
try {
248+
this.log.debug('Turning on CyanAudit...')
249+
const turnOnStart = Date.now()
234250
await this.massiveInstance.query('SET cyanaudit.enabled = 1;')
235251
this.cyanauditEnabled = true
236-
this.log.info('Cyan Audit enabled!')
237-
} catch (e) {
238-
this.log.error('Error: ', e)
252+
const turnOnTime = Date.now() - turnOnStart
253+
this.log.info(`Turned on CyanAudit (${turnOnTime}ms)`)
254+
} catch (err) {
255+
this.log.error(err)
239256
throw new CyanAuditError(true)
240257
}
241258
}
@@ -244,9 +261,13 @@ export class MassiveActionHandler extends AbstractActionHandler {
244261
private async turnOffCyanAudit(): Promise<void> {
245262
if (this.cyanauditEnabled) {
246263
try {
264+
this.log.debug('Turning off CyanAudit...')
265+
const turnOffStart = Date.now()
247266
await this.massiveInstance.query('SET cyanaudit.enabled = 0;')
248267
this.cyanauditEnabled = false
249-
this.log.info('Cyan Audit disabled!')
268+
this.log.info('Turned off CyanAudit')
269+
const turnOffTime = Date.now() - turnOffStart
270+
this.log.info(`Turned off CyanAudit (${turnOffTime}ms)`)
250271
} catch (e) {
251272
this.log.error('Error: ', e)
252273
throw new CyanAuditError(false)
@@ -268,8 +289,9 @@ export class MassiveActionHandler extends AbstractActionHandler {
268289
db.txid = (await tx.instance.one('select txid_current()')).txid_current
269290
try {
270291
await handle(db)
271-
} catch (e) {
272-
throw e // Throw error to trigger ROLLBACK
292+
} catch (err) {
293+
this.log.debug('Error thrown in updater, triggering rollback')
294+
throw err
273295
}
274296
}, {
275297
mode: new this.massiveInstance.pgp.txMode.TransactionMode({

src/MigrationRunner.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import Docker from 'dockerode'
22
import massive from 'massive'
33
import * as path from 'path'
44
import { IDatabase } from 'pg-promise'
5+
import * as Logger from 'bunyan'
56
import { Migration } from './Migration'
67
import { MigrationRunner } from './MigrationRunner'
78
import * as dockerUtils from './testHelpers/docker'
@@ -14,6 +15,8 @@ const dbPass = 'docker'
1415

1516
const baseDir = path.join(path.resolve('./'), 'src')
1617

18+
const log = Logger.createLogger({ name: 'TestMigrationRunner', level: 'debug' })
19+
1720
class TestMigrationRunner extends MigrationRunner {
1821
public async _checkOrCreateSchema() { await this.checkOrCreateSchema() }
1922
public async _checkOrCreateTables() { await this.checkOrCreateTables() }
@@ -80,6 +83,7 @@ describe('Database setup', () => {
8083
massiveInstance.instance,
8184
[],
8285
'newschema',
86+
log,
8387
)
8488
await runner._checkOrCreateSchema()
8589
await runner._checkOrCreateTables() // Schema needs something inside to be seen by Massive
@@ -91,6 +95,8 @@ describe('Database setup', () => {
9195
const runner = new TestMigrationRunner(
9296
massiveInstance.instance,
9397
[],
98+
'public',
99+
log,
94100
)
95101
await runner.setup()
96102
await massiveInstance.reload()
@@ -105,6 +111,7 @@ describe('Database setup', () => {
105111
massiveInstance.instance,
106112
[],
107113
'doesntexist',
114+
log,
108115
)
109116
const schemaError = Error(
110117
`Schema 'doesntexist' does not exist. Make sure you have run \`setup()\` before migrating`,
@@ -160,6 +167,7 @@ describe('MigrationRunner', () => {
160167
massiveInstance.instance,
161168
migrations,
162169
schemaName,
170+
log,
163171
)
164172
await runner.setup()
165173
await massiveInstance.reload()

src/MigrationRunner.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import * as path from 'path'
2+
import * as Logger from 'bunyan'
23
import { IDatabase } from 'pg-promise'
34
import {
45
ExtraMigrationHistoryError,
@@ -15,6 +16,7 @@ export class MigrationRunner {
1516
protected pgp: IDatabase<{}>,
1617
protected migrations: Migration[],
1718
protected schemaName: string = 'public',
19+
protected log: Logger,
1820
skipSetup = false,
1921
) {
2022
const migrationNames = migrations.map((f) => f.name)
@@ -28,10 +30,12 @@ export class MigrationRunner {
2830
}
2931

3032
public async setup() {
33+
this.log.debug('Setting up Migration Runner...')
3134
await this.checkOrCreateSchema()
3235
await this.checkOrCreateTables()
3336
await this.installCyanAudit()
3437
this.isSetUp = true
38+
this.log.debug('Set up Migration Runner')
3539
}
3640

3741
public async migrate(
@@ -48,14 +52,20 @@ export class MigrationRunner {
4852
}
4953

5054
protected async applyMigration(pgp: IDatabase<{}>, migration: Migration, sequenceName: string, blockNumber: number) {
55+
const applyStart = Date.now()
56+
this.log.debug(`Applying migration '${migration.name}'...`)
5157
await migration.up(pgp)
5258
await this.refreshCyanAudit()
5359
await this.registerMigration(pgp, migration.name, sequenceName, blockNumber)
60+
const applyTime = Date.now() - applyStart
61+
this.log.info(`Applied migration '${migration.name}' (${applyTime}ms)`)
5462
}
5563

5664
// public async revertTo(migrationName) {} // Down migrations
5765

5866
protected async checkOrCreateTables() {
67+
this.log.debug(`Creating internally-needed tables if they don't already exist...`)
68+
const createStart = Date.now()
5969
await this.pgp.none(`
6070
CREATE TABLE IF NOT EXISTS $1:raw._migration(
6171
id serial PRIMARY KEY,
@@ -82,22 +92,32 @@ export class MigrationRunner {
8292
txid bigint NOT NULL
8393
);
8494
`, [this.schemaName])
95+
const createTime = Date.now() - createStart
96+
this.log.debug(`Created internally-needed tables if they didn't already exist (${createTime}ms)`)
8597
}
8698

8799
protected async checkOrCreateSchema() {
100+
this.log.debug(`Creating schema '${this.schemaName}' if it doesn't already exist...`)
101+
const createStart = Date.now()
88102
await this.pgp.none(`
89103
CREATE SCHEMA IF NOT EXISTS $1:raw;
90104
`, [this.schemaName])
105+
const createTime = Date.now() - createStart
106+
this.log.debug(`Created schema '${this.schemaName}' if it didn't already exist (${createTime}ms)`)
91107
}
92108

93109
protected async installCyanAudit() {
110+
this.log.debug('Installing CyanAudit to database...')
111+
const installStart = Date.now()
94112
const cyanaudit = new Migration('', '', path.join(__dirname, 'cyanaudit/cyanaudit--2.2.0.sql'))
95113
await cyanaudit.up(this.pgp)
96114

97115
const cyanauditExt = new Migration('', '', path.join(__dirname, 'cyanaudit/cyanaudit-ext.sql'))
98116
await cyanauditExt.up(this.pgp)
99117

100118
await this.refreshCyanAudit()
119+
const installTime = Date.now() - installStart
120+
this.log.info(`Installed CyanAudit to database (${installTime}ms)`)
101121
}
102122

103123
protected async refreshCyanAudit(pgp: IDatabase<{}> = this.pgp) {

0 commit comments

Comments
 (0)