jli  Linuxx86_641.10.3v1.10.30b4590a5507d3f3046e5bafc007cacbbfc9b310b LoggingExtrasvSzԗ6l7b6 </opt/julia/packages/LoggingExtras/VLO3o/src/LoggingExtras.jlhAhUXM=T{VLoggingJ/opt/julia/packages/LoggingExtras/VLO3o/src/CompositionalLoggers/common.jlhAR/opt/julia/packages/LoggingExtras/VLO3o/src/CompositionalLoggers/activefiltered.jlhAQ/opt/julia/packages/LoggingExtras/VLO3o/src/CompositionalLoggers/earlyfiltered.jlhAT/opt/julia/packages/LoggingExtras/VLO3o/src/CompositionalLoggers/minlevelfiltered.jlhAG/opt/julia/packages/LoggingExtras/VLO3o/src/CompositionalLoggers/tee.jlhAO/opt/julia/packages/LoggingExtras/VLO3o/src/CompositionalLoggers/transformer.jlhAR/opt/julia/packages/LoggingExtras/VLO3o/src/CompositionalLoggers/overridelogger.jlhAA/opt/julia/packages/LoggingExtras/VLO3o/src/Sinks/formatlogger.jlhA?/opt/julia/packages/LoggingExtras/VLO3o/src/Sinks/filelogger.jlhAF/opt/julia/packages/LoggingExtras/VLO3o/src/Sinks/datetime_rotation.jlhAj2 EY8pDates8/opt/julia/packages/LoggingExtras/VLO3o/src/verbosity.jlhA9/opt/julia/packages/LoggingExtras/VLO3o/src/deprecated.jlhA CoremуJ5Basemу]J5MainmуJ5ArgToolsBń x(mуF K5 Artifactsmr-V3|mу K5Base64UlD*_mу> K5CRC32c\y.jmуj K5 FileWatchingXzsy`{,zmуh& K5LibdluVW59˗,mу-" K5LoggingT{VhUXM=mуrU" K5MmapP~:xg,Omу|' K5NetworkOptionsC0YW,mуʠ, K5SHAQ<$!<%mу1 K5 Serialization [)*k1mу-G K5Sockets1V$ bdސݗmуYBY K5UnicodeP>I>Nrmуeszo K5 LinearAlgebraSm7̏mуuux K5 OpenBLAS_jll[(Śb6EcQ FmуDux K5libblastrampoline_jllLSۆ }lxӠmу^} K5MarkdownZPn7z`smу/Ed~ K5Printfg^cX׸QDmу;h K5Random_ɢ?\Ymу? K5TarOi>աmу!t, K5DatesEY8pj2 mуX K5FuturebS;3{I xVMmуsD K5InteractiveUtilsWL ~@'ZmуVg K5LibGit2Z[&RPTv3EКRmу8J K5 LibGit2_jll YXg}]$mуD K5 MbedTLS_jllAX 3ȡ_mу- K5 LibSSH2_jlloTZk)߆ using Logging, LoggingExtras julia> logger = FormatLogger() do io, args println(io, args._module, " | ", "[", args.level, "] ", args.message) end; julia> with_logger(logger) do @info "This is an informational message." @warn "This is a warning, should take a look." end Main | [Info] This is an informational message. Main | [Warn] This is a warning, should take a look. ``` """ function FormatLogger(f::Function, io::IO=stderr; always_flush=true) return FormatLogger(f, io, always_flush) end """ FormatLogger(f::Function, path::AbstractString; append=false, always_flush=true) Logger sink that formats the message and writes it to the file at `path`. This is similar to `FileLogger` except that it allows specifying the printing format. To append to the file (rather than truncating the file first), use `append=true`. If `always_flush=true` the stream is flushed after every handled log message. """ function FormatLogger(f::Function, path::AbstractString; append::Bool=false, kw...) io = open(path, append ? "a" : "w") return FormatLogger(f, io; kw...) end function handle_message(logger::FormatLogger, args...; kwargs...) log_args = handle_message_args(args...; kwargs...) # We help the user by passing an IOBuffer to the formatting function # to make sure that everything writes to the logger io in one go. iob = IOBuffer() ioc = IOContext(iob, logger.stream) logger.f(ioc, log_args) write(logger.stream, take!(iob)) logger.always_flush && flush(logger.stream) return nothing end shouldlog(logger::FormatLogger, arg...) = true min_enabled_level(logger::FormatLogger) = BelowMinLevel catch_exceptions(logger::FormatLogger) = true # Or false? SimpleLogger doesn't, ConsoleLogger does. ?/opt/julia/packages/LoggingExtras/VLO3o/src/Sinks/filelogger.jlstruct FileLogger <: AbstractLogger logger::SimpleLogger always_flush::Bool end """ FileLogger(path::AbstractString; append=false, always_flush=true) Create a logger sink that write messages to a file specified with `path`. To append to the file (rather than truncating the file first), use `append=true`. If `always_flush=true` the stream is flushed after every handled log message. !!! note `FileLogger` uses the same output formatting as `SimpleLogger`. Use a `FormatLogger` instead of a `FileLogger` to control the output formatting. """ function FileLogger(path; append=false, kwargs...) filehandle = open(path, append ? "a" : "w") FileLogger(filehandle; kwargs...) end """ FileLogger(io::IOStream; always_flush=true) Create a logger sink that write messages to the `io::IOStream`. The stream is expected to be open and writeable. If `always_flush=true` the stream is flushed after every handled log message. !!! note `FileLogger` uses the same output formatting as `SimpleLogger`. Use a `FormatLogger` instead of a `FileLogger` to control the output formatting. # Examples ```julia io = open("path/to/file.log", "a") # append to the file logger = FileLogger(io) ``` """ function FileLogger(filehandle::IOStream; always_flush=true) FileLogger(SimpleLogger(filehandle, BelowMinLevel), always_flush) end function handle_message(filelogger::FileLogger, args...; kwargs...) handle_message(filelogger.logger, args...; kwargs...) filelogger.always_flush && flush(filelogger.logger.stream) end shouldlog(filelogger::FileLogger, arg...) = true min_enabled_level(filelogger::FileLogger) = BelowMinLevel catch_exceptions(filelogger::FileLogger) = catch_exceptions(filelogger.logger) F/opt/julia/packages/LoggingExtras/VLO3o/src/Sinks/datetime_rotation.jlusing Dates @doc raw""" DatetimeRotatingFileLogger(dir, file_pattern; always_flush=true, rotation_callback=identity) DatetimeRotatingFileLogger(f::Function, dir, file_pattern; always_flush=true, rotation_callback=identity) Construct a `DatetimeRotatingFileLogger` that rotates its file based on the current date. The constructor takes a log output directory, `dir`, and a filename pattern. The smallest time resolution in the format string determines the frequency of log file rotation, allowing for yearly all the way down to minute-level log rotation. The pattern can be given as a string or as a `Dates.DateFormat`. Note that if you wish to have a filename portion that should not be interpreted as a format string, you may need to escape portions of the filename, as shown in the example below. It is possible to pass a formatter function as the first argument to control the output. The formatting function should be of the form `f(io::IOContext, log_args::NamedTuple)` where `log_args` has the following fields: `(level, message, _module, group, id, file, line, kwargs)`. See [`LoggingExtras.handle_message_args`](@ref) for more information about what each field represents. It is also possible to pass `rotation_callback::Function` as a keyword argument. This function will be called every time a file rotation is happening. The function should accept one argument which is the absolute path to the just-rotated file. The logger will block until the callback function returns. Use `@async` if the callback is expensive. # Examples ```julia # Logger that logs to a new file every day logger = DatetimeRotatingFileLogger(log_dir, raw"\a\c\c\e\s\s-yyyy-mm-dd.\l\o\g") # Logger with a formatter function that rotates the log file hourly logger = DatetimeRotatingFileLogger(log_dir, raw"yyyy-mm-dd-HH.\l\o\g") do io, args println(io, args.level, " | ", args.message) end # Example callback function to compress the recently-closed file compressor(file) = run(`gzip $(file)`) logger = DatetimeRotatingFileLogger(...; rotation_callback=compressor) ``` """ mutable struct DatetimeRotatingFileLogger <: AbstractLogger logger::Union{SimpleLogger,FormatLogger} dir::String filename_pattern::DateFormat next_reopen_check::DateTime always_flush::Bool reopen_lock::ReentrantLock current_file::Union{String,Nothing} rotation_callback::Function end function DatetimeRotatingFileLogger(dir, filename_pattern; always_flush=true, rotation_callback=identity) DatetimeRotatingFileLogger(nothing, dir, filename_pattern; always_flush=always_flush, rotation_callback=rotation_callback) end function DatetimeRotatingFileLogger(f::Union{Function,Nothing}, dir, filename_pattern; always_flush=true, rotation_callback=identity) # Construct the backing logger with a temp IOBuffer that will be replaced # by the correct filestream in the call to reopen! below logger = if f === nothing SimpleLogger(IOBuffer(), BelowMinLevel) else # f isa Function FormatLogger(f, IOBuffer(); always_flush=false) # no need to flush twice end filename_pattern isa DateFormat || (filename_pattern = DateFormat(filename_pattern)) # abspath in case user constructs the logger with a relative path and later cd's. drfl = DatetimeRotatingFileLogger(logger, abspath(dir), filename_pattern, now(), always_flush, ReentrantLock(), nothing, rotation_callback) reopen!(drfl) return drfl end similar_logger(::SimpleLogger, io) = SimpleLogger(io, BelowMinLevel) similar_logger(l::FormatLogger, io) = FormatLogger(l.f, io, l.always_flush) function reopen!(drfl::DatetimeRotatingFileLogger) if drfl.current_file !== nothing # close the old IOStream and pass the file to the callback close(drfl.logger.stream) drfl.rotation_callback(drfl.current_file) end new_file = calc_logpath(drfl.dir, drfl.filename_pattern) drfl.current_file = new_file io = open(new_file, "a") drfl.logger = similar_logger(drfl.logger, io) drfl.next_reopen_check = next_datetime_transition(drfl.filename_pattern) return nothing end """ next_datetime_transition(fmt::DateFormat) Given a DateFormat that is being applied to our filename, what is the next time at which our filepath will need to change? """ function next_datetime_transition(fmt::DateFormat) extract_token(x::Dates.DatePart{T}) where {T} = T token_timescales = Dict( # Milliseconds is the smallest timescale 's' => Millisecond(1), # Seconds 'S' => Second(1), # Minutes 'M' => Minute(1), # Hours 'I' => Hour(1), 'H' => Hour(1), # Days 'd' => Day(1), 'e' => Day(1), 'E' => Day(1), # Month 'm' => Month(1), 'u' => Month(1), 'U' => Month(1), # Year 'y' => Year(1), 'Y' => Year(1), ) # Dates for some reason explicitly does not define equality between the smaller # timescales (Second, Minute, Day, etc..) and the larger, non-constant timescales # (Month, Year). We do so explicitly here, without committing type piracy: custom_isless(x, y) = isless(x, y) custom_isless(x::Union{Millisecond,Second,Minute,Hour,Day}, y::Union{Month, Year}) = true custom_isless(x::Union{Month, Year}, y::Union{Millisecond,Second,Minute,Hour,Day}) = false tokens = filter(t -> isa(t, Dates.DatePart), collect(fmt.tokens)) minimum_timescale = first(sort(map(t -> token_timescales[extract_token(t)], tokens), lt=custom_isless)) if custom_isless(minimum_timescale, Minute(1)) throw(ArgumentError("rotating the logger with sub-minute resolution not supported")) end return ceil(now(), minimum_timescale) end calc_logpath(dir, filename_pattern) = joinpath(dir, Dates.format(now(), filename_pattern)) function handle_message(drfl::DatetimeRotatingFileLogger, args...; kwargs...) lock(drfl.reopen_lock) do if now() >= drfl.next_reopen_check reopen!(drfl) end end handle_message(drfl.logger, args...; kwargs...) drfl.always_flush && flush(drfl.logger.stream) end shouldlog(drfl::DatetimeRotatingFileLogger, arg...) = true min_enabled_level(drfl::DatetimeRotatingFileLogger) = BelowMinLevel catch_exceptions(drfl::DatetimeRotatingFileLogger) = catch_exceptions(drfl.logger) 8/opt/julia/packages/LoggingExtras/VLO3o/src/verbosity.jlfunction restore_callsite_source_position!(expr, src) @assert expr.head == :escape @assert expr.args[1].head == :macrocall @assert expr.args[1].args[2] isa LineNumberNode # used to fix the logging source file + line # since we're lowering our verbose logging macros to the # Logging.jl macros; otherwise, they would always report this (verbosity.jl) # file as the logging callsite expr.args[1].args[2] = src return expr end vlogmacrodocs = """ @debugv N msg args... @infov N msg args... @warnv N msg args... @errorv N msg args... "Verbose" logging macros. Drop in replacements of standard logging macros, but an additional verbosity level `N` is passed to indicate differing verbosity levels for a given log level. The verbosity argument is passed as the `group` argument to the core logging logic as a `LoggingExtras.Verbosity` object. Note these "verbose" logging messages will only be filtered if a filter logger is used. A `LoggingExtras.EarlyFilteredLogger`can be used to filter on the `group.verbosity` argument. For convenience, the [`LoggingExtras.withlevel(f, level; verbosity)`](@ref) function is provided to temporarily wrap the current logger with a log level and verbosity to filter while `f` is executed. """ struct Verbosity verbosity::Int end "$vlogmacrodocs" macro debugv(verbosity::Int, msg, exs...) return restore_callsite_source_position!( esc(:($Base.@debug $msg _group=$(Verbosity(verbosity)) $(exs...))), __source__, ) end "$vlogmacrodocs" macro infov(verbosity::Int, msg, exs...) return restore_callsite_source_position!( esc(:($Base.@info $msg _group=$(Verbosity(verbosity)) $(exs...))), __source__, ) end "$vlogmacrodocs" macro warnv(verbosity::Int, msg, exs...) return restore_callsite_source_position!( esc(:($Base.@warn $msg _group=$(Verbosity(verbosity)) $(exs...))), __source__, ) end "$vlogmacrodocs" macro errorv(verbosity::Int, msg, exs...) return restore_callsite_source_position!( esc(:($Base.@error $msg _group=$(Verbosity(verbosity)) $(exs...))), __source__, ) end "$vlogmacrodocs" macro logmsgv(verbosity::Int, level, msg, exs...) return restore_callsite_source_position!( esc(:($Base.@logmsg $level $msg _group=$(Verbosity(verbosity)) $(exs...))), __source__, ) end """ LoggingExtras.withlevel(f, level; verbosity::Integer=0) Convenience function like `Logging.with_logger` to temporarily wrap the current logger with a level filter while `f` is executed. That is, the current logger will still be used for actual logging, but log messages will first be checked that they meet the `level` log level before being passed on to be logged. For convenience, a `verbosity` keyword argument can be passed which also filters the "verbose logging" messages; see [`@debugv`](@ref), [`@infov`](@ref), [`@warnv`](@ref), [`@errorv`](@ref), and [`@logmsgv`](@ref). !!! note If you are not using any of the LoggingExtras compositional loggers then the level override just applies to the current logger. If on the other hand you are using compositional loggers then the override is applied throughout the current logging tree. This is generally what you want, but do be aware that in the case of the [`TeeLogger`](@ref) all branches of the T are overriden. For more control directly construct the logger you want by making use of [`LevelOverrideLogger`](@ref) and then use `with_logger` to make it active. """ function withlevel(f, level::Union{Int, LogLevel}=Info; verbosity::Integer=0) with_logger(EarlyFilteredLogger( args -> !(args.group isa Verbosity) || verbosity >= args.group.verbosity, propagate_level_override(level, current_logger())) ) do f() end end 9/opt/julia/packages/LoggingExtras/VLO3o/src/deprecated.jl&# There are currently no deprecations. ׁ