Skip to content

Add verbose logging #804

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 29, 2025
Merged

Add verbose logging #804

merged 2 commits into from
Apr 29, 2025

Conversation

kvch
Copy link
Contributor

@kvch kvch commented Apr 29, 2025

This PR adds a new flag called --verbose. If you set it, pgroll will be more verbose.
It logs the following events with contextual info to stdout:

  • starting migration
  • starting operation
  • starting backfilling
  • completing operation
  • completing migration
  • completing backfilling
  • creating versioned schema
  • dropping versioned schema

Example outputs

Create multiple tables table

2025-04-29 12:12:32 INFO  starting migration
                      ├ name: 01_create_tables
                      └ operation_count: 3
2025-04-29 12:12:32 INFO  starting operation
                      ├ operation: create_table
                      ├ name: customers
                      ├ columns: [id name credit_card]
                      ├ comment: <nil>
                      └ constraints: []
2025-04-29 12:12:32 INFO  starting operation
                      ├ operation: create_table
                      ├ name: bills
                      ├ columns: [id date quantity]
                      ├ comment: <nil>
                      └ constraints: []
2025-04-29 12:12:32 INFO  starting operation
                      ├ operation: create_table
                      ├ name: sellers
                      ├ columns: [name zip description]
                      ├ comment: <nil>
                      └ constraints: []
2025-04-29 12:12:32 INFO  created versioned schema for migration
                      ├ migration: 01_create_tables
                      └ schema_name: public_01_create_tables
2025-04-29 12:12:32 INFO  completing migration
                      ├ migration: 01_create_tables
                      └ operation_count: 3
2025-04-29 12:12:32 INFO  completing operation
                      ├ operation: create_table
                      ├ name: customers
                      ├ columns: [id name credit_card]
                      ├ comment: <nil>
                      └ constraints: []
2025-04-29 12:12:32 INFO  completing operation
                      ├ operation: create_table
                      ├ name: bills
                      ├ columns: [id date quantity]
                      ├ comment: <nil>
                      └ constraints: []
2025-04-29 12:12:32 INFO  completing operation
                      ├ operation: create_table
                      ├ name: sellers
                      ├ columns: [name zip description]
                      ├ comment: <nil>
                      └ constraints: []
2025-04-29 12:12:32 INFO  completed migration
                      ├ migration: 01_create_tables
                      └ operation_count: 3
 SUCCESS  New version of the schema available under the postgres "public_01_create_tables" schema

Add foreign key constraint

2025-04-29 12:12:34 INFO  starting migration
                      ├ name: 47_add_table_foreign_key_constraint
                      └ operation_count: 1
2025-04-29 12:12:34 INFO  starting operation
                      ├ operation: create_constraint
                      ├ table: tickets
                      └ name: fk_sellers
2025-04-29 12:12:35 INFO  created versioned schema for migration
                      ├ migration: 47_add_table_foreign_key_constraint
                      └ schema_name: public_47_add_table_foreign_key_constraint
2025-04-29 12:12:35 INFO  backfilling started table: tickets
2025-04-29 12:12:35 INFO  backfilling completed table: tickets
2025-04-29 12:12:35 INFO  completing migration
                      ├ migration: 47_add_table_foreign_key_constraint
                      └ operation_count: 1
2025-04-29 12:12:35 INFO  completing operation
                      ├ operation: create_constraint
                      ├ table: tickets
                      └ name: fk_sellers
2025-04-29 12:12:35 INFO  completing operation
                      ├ operation: alter_column
                      ├ table: tickets
                      ├ column:
                      └ references: fk_sellers
2025-04-29 12:12:35 INFO  completed migration
                      ├ migration: 47_add_table_foreign_key_constraint
                      └ operation_count: 1
 SUCCESS  New version of the schema available under the postgres "public_47_add_table_foreign_key_constraint" schema

Rollback

$ go run . rollback 54_create_index_with_opclass --verbose
2025-04-29 12:13:15 INFO  rolling back migration
                      ├ migration: 54_create_index_with_opclass
                      └ operation_count: 1
2025-04-29 12:13:15 INFO  dropped versioned schema for migration
                      ├ migration: 54_create_index_with_opclass
                      └ schema_name: public_54_create_index_with_opclass
2025-04-29 12:13:15 INFO  rolling back operation
                      ├ operation: create_index
                      ├ name: idx_fruits_custom_opclass
                      ├ table: fruits
                      └ index_type:
2025-04-29 12:13:15 INFO  rolled back migration
                      ├ migration: 54_create_index_with_opclass
                      └ operation_count: 1
 SUCCESS  Migration rolled back. Changes made since the last version have been reverted

Closes #784

@github-actions github-actions bot temporarily deployed to Docs Preview April 29, 2025 10:19 Inactive
@kvch kvch force-pushed the feature-verbose-logging branch from d882fca to 919a694 Compare April 29, 2025 10:21
@github-actions github-actions bot temporarily deployed to Docs Preview April 29, 2025 10:21 Inactive
@kvch kvch marked this pull request as ready for review April 29, 2025 10:25
@kvch kvch requested a review from andrew-farries April 29, 2025 10:25
Copy link
Collaborator

@andrew-farries andrew-farries left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This works nicely as a CLI tool, but couples us tightly to the pterm.Logger type which will be less suitable when using pgroll as a dependency from other Go code. I think it's fine for now but we may want to revisit this.

A general suggestion would be to introduce an interface something like:

  type OperationLogger interface {
      // Operation lifecycle methods
      LogOperationStart(op Operation)
      LogOperationComplete(op Operation)
      LogOperationRollback(op Operation)

      // Specific logging events for common scenarios
      LogBackfillStart(table string)
      LogBackfillComplete(table string)
      LogConstraintValidation(table, constraint string)
      LogSchemaCreation(schemaName string)

      // Generic methods for custom events
      LogInfo(msg string, args ...any)
      LogError(msg string, err error, args ...any)
  }

and implement it for pterm such that the different operations can do:

      logger.LogOperationStart(o)

rather than having to repeat themselves with "starting operation..." etc everywhere.

The loggerArgs methods could then move to the implementation of the OperationLogger interface:

func (l *ptermOperationLogger) extractOperationArgs(op Operation) []any {
      // Extract common fields
      var args []any

      // Type-switch to extract operation-specific fields
      switch o := op.(type) {
      case *OpAddColumn:
          args = append(args,
              "operation", OpNameAddColumn,
              "name", o.Column.Name,
              "type", o.Column.Type,
              "table", o.Table,
              "nullable", o.Column.Nullable,
              "unique", o.Column.Unique,
          )
      case *OpCreateTable:
          args = append(args,
              "operation", OpNameCreateTable,
              "name", o.Name,
          )
          if len(o.Columns) > 0 {
              columnNames := getColumnNames(o.Columns)
              args = append(args, "columns", columnNames)
          }
      // Handle other operation types
      }

      return args
  }

this would keep the operations themselves relatively free of logging concerns. WDYT?

@@ -189,7 +194,9 @@ func (o *OpAddColumn) Complete(ctx context.Context, conn db.DB, s *schema.Schema
return nil
}

func (o *OpAddColumn) Rollback(ctx context.Context, conn db.DB, s *schema.Schema) error {
func (o *OpAddColumn) Rollback(ctx context.Context, logger pterm.Logger, conn db.DB, s *schema.Schema) error {
logger.Info("completing operation", logger.Args(o.loggerArgs()...))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should say rolling back operation

@github-actions github-actions bot temporarily deployed to Docs Preview April 29, 2025 13:21 Inactive
@kvch
Copy link
Contributor Author

kvch commented Apr 29, 2025

As we agreed offline, I am implementing the requested changes in a follow-up PR.

@kvch kvch merged commit 0acb636 into main Apr 29, 2025
30 checks passed
@kvch kvch deleted the feature-verbose-logging branch April 29, 2025 14:13
kvch added a commit that referenced this pull request Apr 30, 2025
As requested in #804, I added a `Logger` interface for verbose mode. I
have kept the interface minimal. I only added an extra `Info` function.
But the idea is that we can extend this interface when we need to emit
more logs.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Verbose mode
2 participants