27

When I run a console application as a WebJob in Windows Azure, after few lines of log it adds a warning:

[05/06/2014 09:42:40 > 21026c: WARN] Reached maximum allowed output lines for this run, to see all of the job's logs you can enable website application diagnostics

And stops logging. I was going through all settings in my Website with BASIC hosting plan but I was unable to find anything that would fix this issue.

How can I enable full webJob logs?

Vojtech B
  • 2,837
  • 7
  • 31
  • 59

2 Answers2

26

The way to enable full (continuous) WebJobs logs is actually in the error message: enable website application diagnostics, you can do this via the Azure portal on the website's CONFIGURE tab, you can set the application logs to go to either the file-system (but only for 12 hours), table storage or blob storage.

Once enabled the full logs for WebJobs will go on the selected storage.

More info on application diagnostics for Azure websites: http://azure.microsoft.com/en-us/documentation/articles/web-sites-enable-diagnostic-log/

Amit Apple
  • 9,034
  • 41
  • 50
  • Is it possible to use NLog file target with WebJobs? I have a continuous job that runs during the night and can sometimes have errors I won't see until the next day and I would like continuous logging with a rolling archive--all of which NLog can do. Is there a path in the file system the WJ has write access to? – kamranicus Oct 08 '14 at 14:18
  • yes, it will be whatever the website has access to which is anything under d:\home (%home%), go to https://{sitename}.scm.azurewebsites.net/debugconsole to see your files and there you can understand where best to put your files / log files – Amit Apple Oct 08 '14 at 19:30
  • 7
    I have a continuous WebJob running and application diagnostics is ON for table storage, still I get `Reached maximum allowed output lines for this run, to see all of the job's logs you can enable website application diagnostics` after some time. The WebJob run a simple C# console app with an infinite while-loop, not using the WebJob SDK. I do a few lines of output every minute using `Console.WriteLine`. Do you have an idea of why I still receive this message? – Christofer Eliasson Dec 16 '14 at 12:45
  • You only see this line in the log file (on the file system) logs to the table storage will not show this and will continue receiving log lines. – Amit Apple Dec 16 '14 at 13:01
  • 1
    @AmitApple I see, then is there some way to tell the site at `https://[mysite].scm.azurewebsites.net/azurejobs/#/jobs/continuous/[myjob]` to show the output of the table storage log, instead of the file system log? – Christofer Eliasson Dec 17 '14 at 12:31
  • No, as currently there is no tagging of these logs so it is impossible to extract the right log lines fir the specific job. You are welcome to open an issue on this in https://github.com/projectkudu/kudu/issues – Amit Apple Dec 18 '14 at 03:27
  • @AmitApple Just opened [a new issue](https://github.com/projectkudu/kudu/issues/1421), as per your request. – Christofer Eliasson Dec 18 '14 at 10:44
  • @AmitApple I don't see an option to select destination for logs in my Web App's "Diagnostic logs" blade. Is there a condition where this is not an available choice? – Michael Teper Jun 11 '15 at 20:07
  • @Michael the new azure portal still doesn't support this, pleae use the current azure portal for configuring application logs for your web app. – Amit Apple Jun 13 '15 at 04:06
  • 6
    This has now moved. Its now in the new portal under the app service and "Diagnostic logs" – crthompson Feb 10 '17 at 02:29
4

You could also potentially use a custom TraceWriter.

Example: https://gist.github.com/aaronhoffman/3e319cf519eb8bf76c8f3e4fa6f1b4ae

JobHost config

static void Main()
{
    var config = new JobHostConfiguration();

    // Log Console.Out to SQL using custom TraceWriter
    // Note: Need to update default Microsoft.Azure.WebJobs package for config.Tracing.Tracers to be exposed/available
    config.Tracing.Tracers.Add(new SqlTraceWriter(
        TraceLevel.Info,
        "{{SqlConnectionString}}",
        "{{LogTableName}}"));

    var host = new JobHost(config);
    host.RunAndBlock();
}

Sample SqlTraceWriter implementation

public class SqlTraceWriter : TraceWriter
{
    private string SqlConnectionString { get; set; }

    private string LogTableName { get; set; }

    public SqlTraceWriter(TraceLevel level, string sqlConnectionString, string logTableName)
        : base(level)
    {
        this.SqlConnectionString = sqlConnectionString;
        this.LogTableName = logTableName;
    }

    public override void Trace(TraceEvent traceEvent)
    {
        using (var sqlConnection = this.CreateConnection())
        {
            sqlConnection.Open();

            using (var cmd = new SqlCommand(string.Format("insert into {0} ([Source], [Timestamp], [Level], [Message], [Exception], [Properties]) values (@Source, @Timestamp, @Level, @Message, @Exception, @Properties)", this.LogTableName), sqlConnection))
            {
                cmd.Parameters.AddWithValue("Source", traceEvent.Source ?? "");
                cmd.Parameters.AddWithValue("Timestamp", traceEvent.Timestamp);
                cmd.Parameters.AddWithValue("Level", traceEvent.Level.ToString());
                cmd.Parameters.AddWithValue("Message", traceEvent.Message ?? "");
                cmd.Parameters.AddWithValue("Exception", traceEvent.Exception?.ToString() ?? "");
                cmd.Parameters.AddWithValue("Properties", string.Join("; ", traceEvent.Properties.Select(x => x.Key + ", " + x.Value?.ToString()).ToList()) ?? "");

                cmd.ExecuteNonQuery();
            }
        }
    }

    private SqlConnection CreateConnection()
    {
        return new SqlConnection(this.SqlConnectionString);
    }
}
Aaron Hoffman
  • 6,604
  • 8
  • 56
  • 61