Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 14 additions & 5 deletions src/WebJobs.Script/Content/Script/functions.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,21 @@ function createFunction(f) {

f = getEntryPoint(f, context);

// configure loggers
var origLog = context.log;
context.log = function () {
value = util.format.apply(null, arguments);
origLog(value);
};
var logLevel = function (traceLevel) {
return function () {
var message = util.format.apply(null, arguments);
origLog({ lvl: traceLevel, msg: message });
};
}
// set default log to 'info'
var log = logLevel(3);
['error', 'warn', 'info', 'verbose'].forEach((level, index) => {
var traceLevel = index + 1;
log[level] = logLevel(traceLevel);
});
context.log = log;

context.done = function (err, result) {
if (context._done) {
Expand Down Expand Up @@ -117,4 +127,3 @@ function getEntryPoint(f, context) {

return f;
}

10 changes: 7 additions & 3 deletions src/WebJobs.Script/Description/Node/NodeFunctionInvoker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Dynamic;
using System.Globalization;
using System.IO;
Expand Down Expand Up @@ -271,12 +272,15 @@ private Dictionary<string, object> CreateScriptExecutionContext(object input, Da
// create a TraceWriter wrapper that can be exposed to Node.js
var log = (Func<object, Task<object>>)(p =>
{
string text = p as string;
if (text != null)
var logData = (IDictionary<string, object>)p;
string message = (string)logData["msg"];
if (message != null)
{
try
{
traceWriter.Info(text);
TraceLevel level = (TraceLevel)logData["lvl"];
var evt = new TraceEvent(level, message);
traceWriter.Trace(evt);
}
catch (ObjectDisposedException)
{
Expand Down
13 changes: 13 additions & 0 deletions test/WebJobs.Script.Tests.Integration/NodeEndToEndTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,19 @@ public async Task Scenario_Logging()
Assert.Equal("This is a test", logEntry["message"]);
Assert.Equal("v6.5.0", (string)logEntry["version"]);
Assert.Equal(testData, logEntry["input"]);

// verify log levels
TraceEvent[] traces = Fixture.TraceWriter.Traces.Where(t => t.Message.Contains("loglevel")).ToArray();
Assert.Equal(TraceLevel.Info, traces[0].Level);
Assert.Equal("loglevel default", traces[0].Message);
Assert.Equal(TraceLevel.Info, traces[1].Level);
Assert.Equal("loglevel info", traces[1].Message);
Assert.Equal(TraceLevel.Verbose, traces[2].Level);
Assert.Equal("loglevel verbose", traces[2].Message);
Assert.Equal(TraceLevel.Warning, traces[3].Level);
Assert.Equal("loglevel warn", traces[3].Message);
Assert.Equal(TraceLevel.Error, traces[4].Level);
Assert.Equal("loglevel error", traces[4].Message);
}

[Fact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ var assert = require('assert');
context.log(1234);
context.log(true);

context.log('loglevel default');
context.log.info('loglevel info');
context.log.verbose('loglevel verbose');
context.log.warn('loglevel warn');
context.log.error('loglevel error');

context.done();
}
else if (scenario == 'bindingData') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ describe('functions', () => {
var func = functions.createFunction((context) => {
context.done();
context.done();
expect(logs[0]).to.match(/Error: 'done' has already been called.*/);
expect(logs[0].msg).to.match(/Error: 'done' has already been called.*/);
});

func(context, () => {});
Expand All @@ -244,12 +244,34 @@ describe('functions', () => {

func(context, () => {
setImmediate(() => {
expect(logs[0]).to.match(/Error: Choose either to return a promise or call 'done'.*/);
expect(logs[0].msg).to.match(/Error: Choose either to return a promise or call 'done'.*/);
done();
});
});
});

it('logs to respective level', (done) => {
var func = functions.createFunction((context) => {
context.log('default');
context.log.error('error');
context.log.warn('warn');
context.log.info('info');
context.log.verbose('verbose');
context.done();
});

func(context, () => {
expect(logs).to.eql([
{ lvl: 3, msg: 'default' },
{ lvl: 1, msg: 'error' },
{ lvl: 2, msg: 'warn' },
{ lvl: 3, msg: 'info' },
{ lvl: 4, msg: 'verbose' },
])
done();
});
});

it('done passes data to binder', () => {
var func = functions.createFunction((context) => {
context.bindings = { result: 'res' };
Expand Down