ProgressLogging: a package for defining progress logs

Stable Dev Build Status Codecov Coveralls

ProgressLogging.jl is a package for defining progress logs. It can be used to report progress of a loop/loops with time-consuming body:

julia> using ProgressLogging

julia> @progress for i in 1:10

This package does not contain any progress monitors for visualizing the progress of the program. You need to install a package supporting progress logs created by ProgressLogging.jl API. For example:

@logprogress [name] progress [key1=val1 [key2=val2 ...]]

This macro must be used inside @withprogress macro.

Log a progress event with a value progress. The expression progress must be evaluated to be a real number between 0 and 1 (inclusive), a NaN, or a string "done".

Optional first argument name can be used to change the name of the progress bar. Additional keyword arguments are passed to @logmsg.

@progress [name="", threshold=0.005] for i = ..., j = ..., ...
@progress [name="", threshold=0.005] x = [... for i = ..., j = ..., ...]

Show a progress meter named name for the given loop or array comprehension if possible. Update frequency is limited by threshold (one update per 0.5% of progress by default).


Get the progress ID of current lexical scope.

@withprogress [name=""] [parentid=uuid4()] ex

Create a lexical environment in which @logprogress can be used to emit progress log events without manually specifying the log level, _id, and name (log message).

@withprogress name="iterating" begin
    for i = 1:10
        @logprogress i/10

This is used as parentid of root Progresses.

ProgressLogging.Progress(id, [fraction]; [parentid, name, done])

Usage: Progress log record provider

Progress log record can be created by using the following pattern

id = uuid4()
    @info Progress(id)  # create a progress bar
    # some time consuming job
    # ...
    @info Progress(id, 0.1)  # update progress to 10%
    # ...
    @info Progress(id, done = true)  # close the progress bar

It is recommended to use @withprogress, @logprogress, and optionally @progressid to create log records.

Usage: Progress log record consumer (aka progress monitor)

It is recommended to use ProgressLogging.asprogress instead of checking message isa Progress. Progress monitors can retrieve progress-related information from the following properties.


  • fraction::Union{Float64,Nothing}: it can take following values:
    • 0 <= fraction < 1
    • fraction >= 1: completed
    • fraction = nothing: indeterminate progress
  • id::UUID: Identifier of the job whose progress is at fraction.
  • parentid::UUID: The ID of the parent progress. It is set to ProgressLogging.ROOTID when there is no parent progress. This is used for representing progresses of nested jobs. Note that sub-jobs may be executed concurrently; i.e., there can be multiple child jobs for one parent job.
  • name::String: Name of the progress bar.
  • done::Bool: true if the job is done.
ProgressLogging.asprogress(_, name, _, _, id, _, _; progress, ...) :: Union{Progress, Nothing}

Pre-process log record to obtain a Progress object if it is one of the supported format. This is mean to be used with the message positional argument and all keyword arguments passed to Logging.handle_message. Example:

function Logging.handle_message(logger::MyLogger, args...; kwargs...)
    progress = ProgressLogging.asprogress(args...; kwargs...)
    if progress !== nothing
        return # handle progress log record
    # handle normal log record
progress(f::Function; name = "")

Evaluates f with id as its argument and makes sure to destroy the progress bar afterwards. To update the progress bar in f you can call a logging statement like @info or even just @logmsg with _id=id and progress as arguments.

progress can take either of the following values:

  • 0 <= progress < 1: create or update progress bar
  • progress == nothing || progress = NaN: set progress bar to indeterminate progress
  • progress >= 1 || progress == "done": destroy progress bar

The logging message (e.g. "foo" in @info "foo") will be used as the progress bar's name.

Log level must be higher or equal to LogLevel(-1).

ProgressLogging.progress() do id
    for i = 1:10
        @info "iterating" progress=i/10 _id=id