How to use @__FILE__ and @__LINE__ correctly in my own macro?

Hey all :slight_smile:

I’m writing my own logging package. I want to send strings to two places.

function log(s::String, file, line)
    to_log = "$(Dates.now(Dates.UTC)) in $file:$line\n$s\n"
    TrinityApi.information(
        to_log,
        "DebugLogs.@log"
    )
    println(to_log)
end

And here is my macro.

macro log(s::String) 
    file = esc(@__FILE__)
    line = esc(@__LINE__)
    quote
        if IS_LOGGING_ON[]
            log($s, $file, $line)
        end
    end
end

I want to show the line and file in which the macro is called. How would I do that?

These are all macros I’m defining (for completeness):

for f in (
    :log,
    :log_str
)
    @eval macro $f(s::String) 
        file = esc(@__FILE__)
        line = esc(@__LINE__)
        quote
            if IS_LOGGING_ON[]
                log($s, $file, $line)
            end
        end
    end
end

macro log(s::Symbol...)
    quote
        if IS_LOGGING_ON[]
            log(
                join(string.($(esc(s))), " "),
                @__FILE__, @__LINE__
            )
        end
    end
end

macro log(ex::Expr)
    s = string(ex)
    quote
        $(esc(ex))
        if IS_LOGGING_ON[]
            log($s, @__FILE__, @__LINE__)
        end
    end
end

See Module/file/line for log message generated by a macro

1 Like

Are you aware of the LoggingExtras.jl package? In particular, you can use a TeeLogger for sending to multiple places, and a TransformerLogger to modify the log message.

1 Like
module DebugLogs
import TrinityApi
import Dates
export @log, @log_str
const IS_LOGGING_ON = Ref(true)

function log(s::String, file, line)
    to_log = "$(Dates.now(Dates.UTC)) in $file:$line\n$s\n"
    TrinityApi.information(
        to_log,
        "DebugLogs.@log"
    )
    println(to_log)
end

for f in (
    :log,
    :log_str
)
    @eval macro $f(s::String) 
        file = String(__source__.file)
        line = string(__source__.line)
        quote
            if IS_LOGGING_ON[]
                log($s, $file, $line)
            end
        end
    end
end

macro log(s::Symbol...)
    file = String(__source__.file)
    line = string(__source__.line)
    quote
        if IS_LOGGING_ON[]
            log(
                join(string.($(esc(s))), " "),
                $file, $line
            )
        end
    end
end

macro log(ex::Expr)
    s = string(ex)
    file = String(__source__.file)
    line = string(__source__.line)
    quote
        $(esc(ex))
        if IS_LOGGING_ON[]
            log($s, $file, $line)
        end
    end
end


end # module

That works for me :slight_smile:

That will be a project for the future me :slight_smile:
Thank you!