Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GoogleStackdriverTarget for NLog - Added SendJsonPayload property #2256

Merged
merged 4 commits into from Jun 22, 2018

Conversation

snakefoot
Copy link
Contributor

@snakefoot snakefoot commented Jun 11, 2018

Allows you to do this:

    <target name="stackdriver" xsi:type="GoogleStackdriver" projectId="PROJECT_ID" logId="LOG_ID" includeEventProperties="true" sendJsonPayload="true">
      <contextproperty name="exception" layout="${exception:format=tostring}" />
    </target>

@snakefoot
Copy link
Contributor Author

@chrisdunelm Thought that NLog should also support your LogEntry.JsonPayload

Copy link
Contributor

@chrisdunelm chrisdunelm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR :)
Mostly looks good, just a few minor comments; and one question.

}, includeEventProperties: true);
Assert.Single(uploadedEntries);
var entry0 = uploadedEntries[0];
Assert.Equal(string.Empty, entry0.TextPayload?.Trim() ?? string.Empty);

This comment was marked as spam.

This comment was marked as spam.

InternalLogger.Warn(ex, "GoogleStackdriver(Name={0}): Exception at BuildLogEntry with Key={1}", Name, combinedProperty.Key);
logEntry.Labels[combinedProperty.Key] = "null";
if (string.IsNullOrEmpty(combinedProperty.Key))
continue;

This comment was marked as spam.

This comment was marked as spam.

{
logEntry.Labels[combinedProperty.Key] = combinedProperty.Value?.ToString() ?? "null";
if (string.IsNullOrEmpty(combinedProperty.Key))
continue;

This comment was marked as spam.

This comment was marked as spam.

}
catch (Exception ex)

logEntry.JsonPayload = jsonStruct;

This comment was marked as spam.

This comment was marked as spam.

This comment was marked as spam.

@@ -33,6 +33,7 @@ When using default options, logs will appear under these filter settings in the
* **IncludeCallSiteStackTrace** - Include LogEntrySourceLocation extracted from NLog callsite (Also include filename and linenumber)
* **IncludeEventProperties** - Includes structured logging properties from NLog LogEventInfo.Properties
* **IncludeMdlc** - Include async thread context properties from NLog MappedDiagnosticsLogicalContext
* **SendJsonPayload** - Instead of sending properties as custom labels, then they are sent as Json-Properties

This comment was marked as spam.

This comment was marked as spam.

@manxjason
Copy link

Any ETA on this? Exactly what I was waiting for.

@snakefoot
Copy link
Contributor Author

@manxjason Do you have any preference on having the Labels filled when using JsonPayload ?

@manxjason
Copy link

@snakefoot No preference at this point - perhaps in the future but use of Stackdriver is new to us

Copy link
Contributor

@chrisdunelm chrisdunelm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the extra collection support :)
Just a few changes requested...

}

[Fact]
public async Task SingleLogEntryWithJsonCollectionProperties()

This comment was marked as spam.

This comment was marked as spam.

}
return Value.ForStruct(dictionaryStruct);
}
else if (objectValue is System.Collections.ICollection collection)

This comment was marked as spam.

This comment was marked as spam.

This comment was marked as spam.

This comment was marked as spam.

if (objectValue is System.Collections.IDictionary dictionary)
{
var dictionaryStruct = new Struct();
var itemEnumerator = dictionary.GetEnumerator();

This comment was marked as spam.

This comment was marked as spam.

This comment was marked as spam.

}

var itemTypeCode = Convert.GetTypeCode(itemEnumerator.Value);
dictionaryStruct.Fields.Add(dictionaryKey, BuildSimpleJsonValue(itemTypeCode, itemEnumerator.Value));

This comment was marked as spam.

This comment was marked as spam.

This comment was marked as spam.

@chrisdunelm
Copy link
Contributor

@snakefoot From your point of view is this now ready for merging and release?

@snakefoot
Copy link
Contributor Author

@chrisdunelm Yes it looks good to me.

@chrisdunelm
Copy link
Contributor

Great. I'll wait for all CI to go green, then merge. I expect we'll do another beta release of this next week. Thanks very much :)

@chrisdunelm chrisdunelm merged commit c8e228c into googleapis:master Jun 22, 2018
@snakefoot
Copy link
Contributor Author

Nuget package is now available:

https://www.nuget.org/packages/Google.Cloud.Logging.NLog/2.0.0-beta02

@manxjason
Copy link

@snakefoot this is more an Issue but as this PR is fresh and you made it, perhaps you don't mind discussing the following?

Do you have any preference on having the Labels filled when using JsonPayload ?

Hmm i'm starting to think I should have said 'Yes'. Right now we're finding that the labels are being filled, but not with the actual values, but with the type instead for some reason.

So as per the documentation

Order order = new Order
{
    OrderId = 25544,
    Status = OrderStatus.Processing
};

logger.Info("Test {@value1}", order); // object Result:  Test {"OrderId":2, "Status":"Processing"}

Results in looking like this: https://imgur.com/Olav4qc. Note the message format and the Property's value is the name of the type.

Our setup looks like:

GoogleStackdriverTarget googleTarget = new GoogleStackdriverTarget
{
    ProjectId = "234234",
    Name = "desktop app",
    CredentialFile = Path.Combine(@"C:\asdasd.json"),
    Layout = layout,
    IncludeEventProperties = true,
    ContextProperties = ....
{

And our layout:

JsonLayout layout = new JsonLayout
            {
                Attributes =
                {
                    new JsonAttribute("message", "${message}"),
                    new JsonAttribute("type", "${exception:format=Type}"),
                    new JsonAttribute("exception", "${exception:format=Message}"),
                    new JsonAttribute(
                        "innerException",
                        new JsonLayout
                        {
                            Attributes =
                            {
                                new JsonAttribute(
                                    "type",
                                    "${exception:format=:innerFormat=Type:MaxInnerExceptionLevel=1:InnerExceptionSeparator=}"),
                                new JsonAttribute(
                                    "message",
                                    "${exception:format=:innerFormat=Message:MaxInnerExceptionLevel=1:InnerExceptionSeparator=}")
                            },
                            RenderEmptyObject = false,
                            IncludeAllProperties = true,MaxRecursionLimit = 100
                        })
                },
                RenderEmptyObject = false,
                IncludeAllProperties = true, MaxRecursionLimit = 100
            };

@snakefoot
Copy link
Contributor Author

snakefoot commented Jun 28, 2018

@manxjason Not sure I understand why you are using the JsonLayout (It doesn't help when using SendJsonPayload). I would instead put the values you have added with each of the JsonAttributes into the GoogleStackdriverTarget.ContextProperties

I first implemented the NLog-GoogleStackdriverTarget to have the same features as for log4net. And then I added the support for JsonPayload so it would have the same features as for Serilog.

I don't have much experience with the Google Logging Framework to know what works best for you.

Are you missing an RenderEmptyObject option on GoogleStackdriverTarget.ContextProperties ?

@snakefoot
Copy link
Contributor Author

@manxjason Discovered your use of POCO-objects, so created #2300 to support this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants