printStatus prints the progress status, and optionally additionally detailed dump of configuration. `rule` indicates the type of output expected. By default the status is written to standard output, but other writers can be used as well.
(rule PrintStatusRule, writers ...io.Writer)
| 1373 | // By default the status is written to standard output, but other writers can |
| 1374 | // be used as well. |
| 1375 | func (mgtr *Migrator) printStatus(rule PrintStatusRule, writers ...io.Writer) { |
| 1376 | if rule == NoPrintStatusRule { |
| 1377 | return |
| 1378 | } |
| 1379 | writers = append(writers, os.Stdout) |
| 1380 | |
| 1381 | elapsedTime := mgtr.migrationContext.ElapsedTime() |
| 1382 | elapsedSeconds := int64(elapsedTime.Seconds()) |
| 1383 | totalRowsCopied := mgtr.migrationContext.GetTotalRowsCopied() |
| 1384 | rowsEstimate := atomic.LoadInt64(&mgtr.migrationContext.RowsEstimate) + atomic.LoadInt64(&mgtr.migrationContext.RowsDeltaEstimate) |
| 1385 | if atomic.LoadInt64(&mgtr.rowCopyCompleteFlag) == 1 { |
| 1386 | // Done copying rows. The totalRowsCopied value is the de-facto number of rows, |
| 1387 | // and there is no further need to keep updating the value. |
| 1388 | rowsEstimate = totalRowsCopied |
| 1389 | } |
| 1390 | |
| 1391 | // we take the opportunity to update migration context with progressPct |
| 1392 | progressPct := mgtr.getProgressPercent(rowsEstimate) |
| 1393 | mgtr.migrationContext.SetProgressPct(progressPct) |
| 1394 | |
| 1395 | // Before status, let's see if we should print a nice reminder for what exactly we're doing here. |
| 1396 | if mgtr.shouldPrintMigrationStatusHint(rule, elapsedSeconds) { |
| 1397 | mgtr.printMigrationStatusHint(writers...) |
| 1398 | } |
| 1399 | |
| 1400 | // Get state + ETA |
| 1401 | state, eta, etaDuration := mgtr.getMigrationStateAndETA(rowsEstimate) |
| 1402 | mgtr.migrationContext.SetETADuration(etaDuration) |
| 1403 | |
| 1404 | if !mgtr.shouldPrintStatus(rule, elapsedSeconds, etaDuration) { |
| 1405 | return |
| 1406 | } |
| 1407 | |
| 1408 | currentBinlogCoordinates := mgtr.eventsStreamer.GetCurrentBinlogCoordinates() |
| 1409 | |
| 1410 | status := fmt.Sprintf("Copy: %d/%d %.1f%%; Applied: %d; Backlog: %d/%d; Time: %+v(total), %+v(copy); streamer: %+v; Lag: %.2fs, HeartbeatLag: %.2fs, State: %s; ETA: %s", |
| 1411 | totalRowsCopied, rowsEstimate, progressPct, |
| 1412 | atomic.LoadInt64(&mgtr.migrationContext.TotalDMLEventsApplied), |
| 1413 | len(mgtr.applyEventsQueue), cap(mgtr.applyEventsQueue), |
| 1414 | base.PrettifyDurationOutput(elapsedTime), base.PrettifyDurationOutput(mgtr.migrationContext.ElapsedRowCopyTime()), |
| 1415 | currentBinlogCoordinates.DisplayString(), |
| 1416 | mgtr.migrationContext.GetCurrentLagDuration().Seconds(), |
| 1417 | mgtr.migrationContext.TimeSinceLastHeartbeatOnChangelog().Seconds(), |
| 1418 | state, |
| 1419 | eta, |
| 1420 | ) |
| 1421 | mgtr.applier.WriteChangelog( |
| 1422 | fmt.Sprintf("copy iteration %d at %d", mgtr.migrationContext.GetIteration(), time.Now().Unix()), |
| 1423 | state, |
| 1424 | ) |
| 1425 | w := io.MultiWriter(writers...) |
| 1426 | fmt.Fprintln(w, status) |
| 1427 | |
| 1428 | // This "hack" is required here because the underlying logging library |
| 1429 | // github.com/outbrain/golib/log provides two functions Info and Infof; but the arguments of |
| 1430 | // both these functions are eventually redirected to the same function, which internally calls |
| 1431 | // fmt.Sprintf. So, the argument of every function called on the DefaultLogger object |
| 1432 | // migrationContext.Log will eventually pass through fmt.Sprintf, and thus the '%' character |
no test coverage detected