Since performance is in question, I would suggest taking this approach a step further and use 'array of const' instead of 'array of string'. That way, you can pass in integers and other fundamental types as-is and not invoke the overhead of converting them to strings unless you are sure you actually need to, eg:
procedure Log(LogLevel: TLogLevel; const Args: array of const); overload;
begin
if CanLog(LogLevel) then
begin
// convert Args to a log message and write it out as needed...
end;
end;
Log(llTrace, ['Test', GetLastError(), ...]);