Coder Social home page Coder Social logo

gelf4net's Introduction

gelf4net

gelf4net is a log4net adapter that formats logs to the GELF specification and makes it easy to send them over Udp, Amqp or http.

Installation

You can install the latest stable release using on of the the nugets package:

All the libraries supports net46 and netstandard2.0

Configuration

Gelf4Net gives you the ability to log messages either through Udp, Amqp or Http.

Gelf4Net

net46 & netstandard2.0

<?xml version="1.0"?>
<configuration>
    <configSections>
        <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,Log4net"/>
    </configSections>

    <log4net>
        <appender name="GelfUdpAppenderCC" type="Gelf4Net.Appender.GelfUdpAppender, Gelf4Net">
            <remoteAddress value="192.168.44.10" />
            <remotePort value="12201" />
            <layout type="Gelf4Net.Layout.GelfLayout, Gelf4Net">
                <param name="AdditionalFields" value="app:UdpAppenderCC,version:1.0,Environment:Dev,Level:%level" />
                <param name="Facility" value="RandomPhrases" />
                <param name="IncludeLocationInformation" value="true" />
                <param name="SendTimeStampAsString" value="true"/>
                <!-- Sets the full_message and short_message to the specified pattern-->
                <param name="ConversionPattern" value="[%t] %c{1} - %m" />
            </layout>
        </appender>

        <appender name="GelfUdpAppender" type="Gelf4Net.Appender.GelfUdpAppender, Gelf4Net">
            <remoteAddress value="192.168.44.10" />
            <remotePort value="12201" />
            <layout type="Gelf4Net.Layout.GelfLayout, Gelf4Net">
                <param name="AdditionalFields" value="app:UdpAppender,version:1.0,Environment:Dev,Level:%level" />
                <param name="Facility" value="RandomPhrases" />
                <param name="IncludeLocationInformation" value="true" />
                <param name="SendTimeStampAsString" value="false"/>
            </layout>
        </appender>

        <appender name="AsyncGelfUdpAppender" type="Gelf4Net.Appender.AsyncGelfUdpAppender, Gelf4Net">
            <!-- Limit of log lines to buffer for async send. Defaults to 1000-->
<!-- If we cannot connect to graylog and the queue reaches the buffersize it will dequeue messages from the queue-->
            <bufferSize value="2000" />
            <!-- Number of tasks to use for the async appender. 0 or fewer indicates one task per processor-->
            <threads value="2" />
            <remoteAddress value="192.168.44.10" />
            <remotePort value="12201" />
            <layout type="Gelf4Net.Layout.GelfLayout, Gelf4Net">
                <param name="AdditionalFields" value="app:AsyncUdpAppender,version:1.0,Environment:Dev,Level:%level" />
                <param name="Facility" value="RandomPhrases" />
                <param name="IncludeLocationInformation" value="true" />
                <param name="SendTimeStampAsString" value="true"/>
            </layout>
        </appender>

        <appender name="GelfHttpAppender" type="Gelf4Net.Appender.GelfHttpAppender, Gelf4Net">
            <url value="http://192.168.44.10:12201/gelf" />
            <layout type="Gelf4Net.Layout.GelfLayout, Gelf4Net">
                <param name="AdditionalFields" value="app:HttpAppender,version:1.0,Environment:Dev,Level:%level" />
                <param name="Facility" value="RandomPhrases" />
                <param name="IncludeLocationInformation" value="true" />
                <param name="SendTimeStampAsString" value="false"/>
                <!--Sets the full_message and short_message to the specified pattern-->
                <!--<param name="ConversionPattern" value="[%t] %c{1} - %m" />-->
            </layout>
        </appender>

        <appender name="AsyncGelfHttpAppender" type="Gelf4Net.Appender.AsyncGelfHttpAppender, Gelf4Net">
            <url value="http://127.0.0.1:12201/gelf" />
            <!-- Limit of log lines to buffer for async send. Defaults to 1000-->
<!-- If we cannot connect to graylog and the queue reaches the buffersize it will dequeue messages from the queue-->
            <bufferSize value="2000" />
            <!-- Number of tasks to use for the async appender. 0 or fewer indicates one task per processor-->
            <threads value="2" />
            <layout type="Gelf4Net.Layout.GelfLayout, Gelf4Net">
                <param name="AdditionalFields" value="app:AsyncHttpAppender,version:1.0,Environment:Dev,Level:%level" />
                <param name="Facility" value="RandomPhrases" />
                <param name="IncludeLocationInformation" value="true" />
                <param name="SendTimeStampAsString" value="false" />
                <!--Sets the full_message and short_message to the specified pattern-->
                <!--<param name="ConversionPattern" value="[%t] %c{1} - %m" />-->
            </layout>
        </appender>

        <appender name="GelfAmqpAppender" type="Gelf4Net.Appender.GelfAmqpAppender, Gelf4Net">
            <remoteAddress value="192.168.44.10" />
            <remotePort value="5672" />
            <username value="guest" />
            <password value="guest" />
            <virtualHost value="/" />
            <exchange value="log-messages" />
            <key value="#" />
            <layout type="Gelf4Net.Layout.GelfLayout, Gelf4Net">
                <param name="AdditionalFields" value="app:GelfAmqpAppender,version:1.0,Level:%level" />
                <param name="Facility" value="RandomPhrases" />
                <param name="IncludeLocationInformation" value="true" />
                <param name="SendTimeStampAsString" value="false"/>
                <!-- Sets the full_message and short_message to the specified pattern-->
                <!--<param name="ConversionPattern" value="[%t] %c{1} - %m" />-->
            </layout>
        </appender>

        <appender name="AsyncGelfAmqpAppender" type="Gelf4Net.Appender.AsyncGelfAmqpAppender, Gelf4Net">
            <!-- Limit of log lines to buffer for async send. Defaults to 1000-->
<!-- If we cannot connect to graylog and the queue reaches the buffersize it will dequeue messages from the queue-->
            <bufferSize value="2000" />
            <!-- Number of tasks to use for the async appender. 0 or fewer indicates one task per processor-->
            <threads value="2" />
            <remoteAddress value="192.168.44.10" />
            <remotePort value="5672" />
            <username value="guest" />
            <password value="guest" />
            <virtualHost value="/" />
            <exchange value="log-messages" />
            <key value="#" />
            <layout type="Gelf4Net.Layout.GelfLayout, Gelf4Net">
                <param name="AdditionalFields" value="app:AsyncGelfAmqpAppender,version:1.0,Level:%level" />
                <param name="Facility" value="RandomPhrases" />
                <param name="IncludeLocationInformation" value="true" />
                <!-- Sets the full_message and short_message to the specified pattern-->
                <!--<param name="ConversionPattern" value="[%t] %c{1} - %m" />-->
            </layout>
        </appender>

        <root>
            <level value="ALL" />
            <appender-ref ref="GelfUdpAppender" />
            <appender-ref ref="GelfUdpAppenderCC" />
            <appender-ref ref="AsyncGelfUdpAppender" />
            <appender-ref ref="GelfHttpAppender" />
            <appender-ref ref="AsyncGelfHttpAppender" />
            <appender-ref ref="GelfAmqpAppender" />
            <appender-ref ref="AsyncGelfAmqpAppender" />
        </root>
    </log4net>
</configuration>

Gelf4Net.AmqpAppender

net46

<log4net>
    <appender name="GelfAmqpAppender" type="Gelf4Net.Appender.GelfAmqpAppender, Gelf4Net.AmqpAppender">
        <remoteAddress value="192.168.44.10" />
        <remotePort value="5672" />
        <username value="guest" />
        <password value="guest" />
        <virtualHost value="/" />
        <exchange value="log-messages" />
        <key value="#" />
        <layout type="Gelf4Net.Layout.GelfLayout, Gelf4Net.AmqpAppender">
            <param name="AdditionalFields" value="app:GelfAmqpAppender,version:1.0,Level:%level" />
            <param name="Facility" value="RandomPhrases" />
            <param name="IncludeLocationInformation" value="true" />
            <param name="SendTimeStampAsString" value="false"/>
            <!-- Sets the full_message and short_message to the specified pattern-->
            <!--<param name="ConversionPattern" value="[%t] %c{1} - %m" />-->
        </layout>
    </appender>

    <appender name="AsyncGelfAmqpAppender" type="Gelf4Net.Appender.AsyncGelfAmqpAppender, Gelf4Net.AmqpAppender">
        <!-- Limit of log lines to buffer for async send. Defaults to 1000-->
<!-- If we cannot connect to graylog and the queue reaches the buffersize it will dequeue messages from the queue-->
        <bufferSize value="2000" />
        <!-- Number of tasks to use for the async appender. 0 or fewer indicates one task per processor-->
        <threads value="2" />
        <remoteAddress value="192.168.44.10" />
        <remotePort value="5672" />
        <username value="guest" />
        <password value="guest" />
        <virtualHost value="/" />
        <exchange value="log-messages" />
        <key value="#" />
        <layout type="Gelf4Net.Layout.GelfLayout, Gelf4Net.AmqpAppender">
            <param name="AdditionalFields" value="app:AsyncGelfAmqpAppender,version:1.0,Level:%level" />
            <param name="Facility" value="RandomPhrases" />
            <param name="IncludeLocationInformation" value="true" />
            <param name="SendTimeStampAsString" value="false"/>
            <!-- Sets the full_message and short_message to the specified pattern-->
            <!--<param name="ConversionPattern" value="[%t] %c{1} - %m" />-->
        </layout>
    </appender>

    <root>
        <level value="ALL" />
        <appender-ref ref="GelfAmqpAppender" />
        <appender-ref ref="AsyncGelfAmqpAppender" />
    </root>
</log4net>

netstandard2.0

<log4net>
    <appender name="GelfAmqpAppender" type="Gelf4Net.Appender.GelfAmqpAppender, Gelf4Net.AmqpAppender">
        <remoteAddress value="192.168.44.10" />
        <remotePort value="5672" />
        <username value="guest" />
        <password value="guest" />
        <virtualHost value="/" />
        <exchange value="log-messages" />
        <key value="#" />
        <layout type="Gelf4Net.Layout.GelfLayout, Gelf4Net.Core">
            <param name="AdditionalFields" value="app:DotnetcoreGelfAmqpAppender,version:1.0,Level:%level" />
            <param name="Facility" value="RandomPhrases" />
            <param name="IncludeLocationInformation" value="true" />
            <param name="SendTimeStampAsString" value="false"/>
        </layout>
    </appender>

    <appender name="AsyncGelfAmqpAppender" type="Gelf4Net.Appender.AsyncGelfAmqpAppender, Gelf4Net.AmqpAppender">
        <!-- Limit of log lines to buffer for async send. Defaults to 1000-->
<!-- If we cannot connect to graylog and the queue reaches the buffersize it will dequeue messages from the queue-->
        <bufferSize value="2000" />
        <!-- Number of tasks to use for the async appender. 0 or fewer indicates one task per processor-->
        <threads value="2" />
        <remoteAddress value="192.168.44.10" />
        <remotePort value="5672" />
        <username value="guest" />
        <password value="guest" />
        <virtualHost value="/" />
        <exchange value="log-messages" />
        <key value="#" />
        <layout type="Gelf4Net.Layout.GelfLayout, Gelf4Net.Core">
            <param name="AdditionalFields" value="app:DotnetcoreAsyncGelfAmqpAppender,version:1.0,Level:%level" />
            <param name="Facility" value="RandomPhrases" />
            <param name="IncludeLocationInformation" value="true" />
            <param name="ConversionPattern" value="[%t] %c{1} - %m" />
        </layout>
    </appender>

    <root>
        <level value="ALL" />
        <appender-ref ref="GelfAmqpAppender" />
        <appender-ref ref="AsyncGelfAmqpAppender" />
    </root>
</log4net>

Gelf4Net.HttpAppender

net46

<log4net>
    <appender name="GelfHttpAppender" type="Gelf4net.Appender.GelfHttpAppender, Gelf4Net.HttpAppender">
        <url value="http://192.168.44.10:12201/gelf" />
        <layout type="Gelf4net.Layout.GelfLayout, Gelf4Net.HttpAppender">
            <param name="AdditionalFields" value="app:GelfHttpAppender,version:1.0,Environment:Dev,Level:%level" />
            <param name="Facility" value="RandomPhrases" />
            <param name="IncludeLocationInformation" value="true" />
            <param name="SendTimeStampAsString" value="false"/>
            <!-- Sets the full_message and short_message to the specified pattern-->
            <param name="ConversionPattern" value="[%t] %c{1} - %m" />
        </layout>
    </appender>

    <appender name="AsyncGelfHttpAppender" type="Gelf4Net.Appender.AsyncGelfHttpAppender, Gelf4Net.HttpAppender">
      <!-- Limit of log lines to buffer for async send. Defaults to 1000-->
<!-- If we cannot connect to graylog and the queue reaches the buffersize it will dequeue messages from the queue-->
      <bufferSize value="2000" />
      <!-- Number of tasks to use for the async appender. 0 or fewer indicates one task per processor-->
      <threads value="2" />
      <url value="http://127.0.0.1:12201/gelf" />
      <layout type="Gelf4net.Layout.GelfLayout, Gelf4Net.HttpAppender">
        <param name="AdditionalFields" value="app:AsyncGelfHttpAppender,version:1.0,Environment:Dev,Level:%level" />
        <param name="Facility" value="SimpleConsoleApplicationHttpPackage" />
        <param name="IncludeLocationInformation" value="true" />
        <param name="SendTimeStampAsString" value="false" />
        <!--Sets the full_message and short_message to the specified pattern-->
        <!--<param name="ConversionPattern" value="[%t] %c{1} - %m" />-->
      </layout>
    </appender>

    <root>
        <level value="ALL" />
        <appender-ref ref="GelfHttpAppender" />
        <appender-ref ref="AsyncGelfHttpAppender" />
    </root>
</log4net>

netstandard2.0

<log4net>

    <appender name="GelfHttpAppender" type="Gelf4Net.Appender.GelfHttpAppender, Gelf4Net.HttpAppender">
        <url value="http://192.168.44.10:12201/gelf" />
        <layout type="Gelf4Net.Layout.GelfLayout, Gelf4Net.Core">
            <param name="AdditionalFields" value="app:DotnetcoreHttpAppender,version:1.0,Environment:Dev,Level:%level" />
            <param name="Facility" value="RandomPhrases" />
            <param name="IncludeLocationInformation" value="true" />
        </layout>
    </appender>

    <appender name="AsyncGelfHttpAppender" type="Gelf4Net.Appender.AsyncGelfHttpAppender, Gelf4Net.HttpAppender">
      <!-- Limit of log lines to buffer for async send. Defaults to 1000-->
<!-- If we cannot connect to graylog and the queue reaches the buffersize it will dequeue messages from the queue-->
      <bufferSize value="2000" />
      <!-- Number of tasks to use for the async appender. 0 or fewer indicates one task per processor-->
      <threads value="2" />
      <url value="http://127.0.0.1:12201/gelf" />
      <layout type="Gelf4net.Layout.GelfLayout, Gelf4Net.Core">
        <param name="AdditionalFields" value="app:DotnetcoreAsyncGelfHttpAppender,version:1.0,Environment:Dev,Level:%level" />
        <param name="Facility" value="SimpleConsoleApplicationHttpPackage" />
        <param name="IncludeLocationInformation" value="true" />
        <param name="SendTimeStampAsString" value="false" />
        <!--Sets the full_message and short_message to the specified pattern-->
        <!--<param name="ConversionPattern" value="[%t] %c{1} - %m" />-->
      </layout>
    </appender>

    <root>
        <level value="ALL" />
        <appender-ref ref="GelfHttpAppender" />
    </root>
</log4net>

Gelf4Net.UdpAppender

net46

<log4net>
    <appender name="AsyncGelfUdpAppender" type="Gelf4Net.Appender.AsyncGelfUdpAppender, Gelf4Net.UdpAppender">
        <!-- Limit of log lines to buffer for async send. Defaults to 1000-->
<!-- If we cannot connect to graylog and the queue reaches the buffersize it will dequeue messages from the queue-->
        <bufferSize value="2000" />
        <!-- Number of tasks to use for the async appender. 0 or fewer indicates one task per processor-->
        <threads value="2" />
        <remoteAddress value="192.168.44.10" />
        <remotePort value="12201" />
        <maxChunkSize value="3" />
        <layout type="Gelf4Net.Layout.GelfLayout, Gelf4Net.UdpAppender">
            <param name="AdditionalFields" value="app:AsyncGelfUdpAppender,version:1.0,Environment:Dev,Level:%level" />
            <param name="Facility" value="RandomPhrases" />
            <param name="IncludeLocationInformation" value="true" />
            <param name="SendTimeStampAsString" value="false"/>
        </layout>
    </appender>

    <appender name="GelfUdpAppender" type="Gelf4Net.Appender.GelfUdpAppender, Gelf4Net.UdpAppender">
        <remoteAddress value="192.168.44.10" />
        <remotePort value="12201" />
        <layout type="Gelf4Net.Layout.GelfLayout, Gelf4Net.UdpAppender">
            <param name="AdditionalFields" value="app:GelfUdpAppender,version:1.0,Environment:Dev,Level:%level" />
            <param name="Facility" value="RandomPhrases" />
            <param name="IncludeLocationInformation" value="true" />
        </layout>
    </appender>

    <root>
        <level value="ALL" />
        <appender-ref ref="GelfUdpAppender" />
        <appender-ref ref="AsyncGelfUdpAppender" />
    </root>
</log4net>

dotnetstandard2.0

<log4net>
    <appender name="GelfUdpAppenderCC" type="Gelf4Net.Appender.GelfUdpAppender, Gelf4Net.UdpAppender">
        <remoteAddress value="192.168.44.10" />
        <remotePort value="12201" />
        <layout type="Gelf4Net.Layout.GelfLayout, Gelf4Net.Core">
            <param name="AdditionalFields" value="app:DotnetcoreUdpAppenderCC,version:1.0,Environment:Dev,Level:%level" />
            <param name="Facility" value="RandomPhrases" />
            <param name="IncludeLocationInformation" value="true" />
            <param name="ConversionPattern" value="[%t] %c{1} - %m" />
        </layout>
    </appender>

    <appender name="GelfUdpAppender" type="Gelf4Net.Appender.GelfUdpAppender, Gelf4Net.UdpAppender">
        <remoteAddress value="192.168.44.10" />
        <remotePort value="12201" />
        <layout type="Gelf4Net.Layout.GelfLayout, Gelf4Net.Core">
            <param name="AdditionalFields" value="app:DotnetcoreUdpAppender,version:1.0,Environment:Dev,Level:%level" />
            <param name="Facility" value="RandomPhrases" />
            <param name="IncludeLocationInformation" value="true" />
            <param name="SendTimeStampAsString" value="false"/>
        </layout>
    </appender>

    <appender name="AsyncGelfUdpAppender" type="Gelf4Net.Appender.AsyncGelfUdpAppender, Gelf4Net.UdpAppender">
        <!-- Limit of log lines to buffer for async send. Defaults to 1000-->
<!-- If we cannot connect to graylog and the queue reaches the buffersize it will dequeue messages from the queue-->
        <bufferSize value="2000" />
        <!-- Number of tasks to use for the async appender. 0 or fewer indicates one task per processor-->
        <threads value="2" />
        <remoteAddress value="127.0.0.1" />
        <remotePort value="12201" />
        <maxChunkSize value="3" />
        <layout type="Gelf4Net.Layout.GelfLayout, Gelf4Net.Core">
            <param name="AdditionalFields" value="app:DotnetcoreAsyncUdpAppender,version:1.0,Environment:Dev,Level:%level" />
            <param name="Facility" value="SimpleConsoleApplicationUdpPackage" />
            <param name="IncludeLocationInformation" value="true" />
        </layout>
    </appender>

    <root>
        <level value="ALL" />
        <appender-ref ref="GelfUdpAppender" />
        <appender-ref ref="GelfUdpAppenderCC" />
        <appender-ref ref="AsyncGelfUdpAppender" />
    </root>
</log4net>

Additional Properties

There are several ways that additional properties can be added to a log.

Configuration Any static information can be set through configuration by adding a comma separated list of key:value pairs. You can also use conversion patterns like you would if you were using the PatternLayout class:

<layout type="Gelf4net.Layout.GelfLayout, Gelf4net">
    <param name="AdditionalFields" value="app:RandomSentence,version:1.0,Level:%level" />
</layout>

This will add the following fields to your GELF log:

{
    ...
    "_app":"RandomSentence",
    "_version":"1.0",
    "_Level":"DEBUG",
    ...
}

You can also use your own custom field and key/value separators to deal with the case when the additional fields contain commas or colons

<layout type="Gelf4net.Layout.GelfLayout, Gelf4net">
    <param name="AdditionalFields" value="app¬:¬RandomSentence¬|¬version:1.0¬|¬Level¬:¬%level" />
    <param name="FieldSeparator" value="¬|¬" />
    <param name="KeyValueSeparator" value="¬:¬" />
</layout>

Custom Properties Any properties you add to the log4net.ThreadContext.Properties object will automatically be added to the message as additional fields

log4net.ThreadContext.Properties["TraceID"] = Guid.NewGuid();

This will be added to the log:

{
    ...
    "_TraceID":"3449DDF8-C3B4-46DD-8B83-0BDF1ABC92E2",
    ...
}

Custom Objects You can use custom objects to log additional fields to the output. Here is an example:

_logger.Debug(new {
    Type = "Request",
    Method = request.Method,
    Url = request.Url
});

This will add the following additional fields to the output:

{
    ...
    "_Type":"Request",
    "_Method":"GET",
    "_Url":"http://whatever.com/gelf",
    ...
}

Under the hood the GelfLayout class takes any object that is not a string and adds it's public properties to a dictionary. All non-numeric values are then converted in to strings. You can also pass in a dictionary directly and get the same output. When passing in a dictionary rather than using the public properties of the object it uses the Key/Value pairs stored internally.

_logger.Debug(new Dictionary<string,string>{
    { "Type", "Request" },
    { "Method", request.Method },
    { "Url", request.Url.ToString() }
});

Formatting Messages

If you are just logging a simple string then that message will show up in the full_message and be truncated to 250 characters in the short_message field.

_logger.Debug("This is a ridiculously short message but pretending it's longer than 250 characters");

Pretending the previous message is longer than 250 characters, this will be your output:

{
    ...
    "full_message":"This is a ridiculously short message but pretending it's longer than 250 characters",
    "short_message":"This is a ridiculously short message but pretending",
    ...
}

If you want to format your message using a conversion pattern you can do so by specifying the ConversionPattern parameter. Again you can specify all the same parameters that you would if you were using the PatternLayout.

          <layout type="Gelf4net.Layout.GelfLayout, Gelf4net">
            <param name="ConversionPattern" value="[%t] %c{1} - %m" />
          </layout>

You can also specify the message when logging custom objects:

_logger.Debug(new Dictionary<string,string>{
    { "Type", "Request" },
    { "Method", request.Method },
    { "Message", request.RawUrl }
    { "ShortMessage", request.Url.ToString() }
});

If the custom object does not have a Message or ShortMessage field than the message will be the output of the ToString() of that object.

dotnetstandard1.5 Appenders

dotnetstandard1.5~Appenders doesn't log the file an line...

Custom LoggingEventData

Using LoggingEventData with all the goodies of gelf4net.

Remember if you're not setting the LocationInfo in LoggingEventData you should set it to false in the appender configuration <param name="IncludeLocationInformation" value="false"/>

var loggingEventData = new LoggingEventData
{
    Message = "This is a message",
    LoggerName = "Test.Logger.Class",
    Level = Level.Debug,
    TimeStamp = DateTime.Now
};
var loggingEvent = new LoggingEvent(loggingEventData);

If you want to send a custom properties, serialize the object.

var customObject = new {
    Type = "Request",
    Method = request.Method,
    Url = request.Url
}

var loggingEventData = new LoggingEventData
{
    Message = JsonConvert.SerializeObject(customObject),
    LoggerName = "Test.Logger.Class",
    Level = Level.Debug,
    TimeStamp = DateTime.Now
};
var loggingEvent = new LoggingEvent(loggingEventData);

AsyncAppender

We have two new parameters in our AsyncAppenders thanks to @iwillspeak and a new AsyncAppender the AsyncGelfHttpAppender

<!-- Limit of log lines to buffer for async send. Defaults to 1000-->
<bufferSize value="2000" />
<!-- Number of tasks to use for the async appender. 0 or fewer indicates one task per processor-->
<threads value="2" />

Thanks

The dotnetcore web project sample was based in http://dotnetliberty.com/index.php/2015/11/09/asp-net-5-logging-with-log4net/

License

This project is licensed under the MIT license

gelf4net's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

gelf4net's Issues

Blocks the application if graylog server is not reachable

While working on server migration, we accidentally forget to allow graylog server in firewall. The log statement was pausing the code execution due to unreachable Graylog server upto 20 seconds before stepping forward.

This poses a serious risk to production environment. Is there anyway we can have log statements are executed asynchronously?

AsyncGelfUdpAppender with Graylog 4

Hi there,
I am currently using Gelf4Net.UdpAppender 1.0.0.18 and Microsoft.Extensions.Logging.Log4Net.AspNetCore 3.1.0 with Graylog 3.3.16 without any issues.

After spinning up Graylog 4.2.5 UdpAppender does not work with following config.

<appender name="gelfAppender" type="Gelf4Net.Appender.AsyncGelfUdpAppender, Gelf4Net.UdpAppender"> <remoteAddress value="127.0.0.1"/> <remotePort value="12201" /> <threshold value="ALL"/> <layout type="Gelf4Net.Layout.GelfLayout, Gelf4Net.Core"> <param name="AdditionalFields" value="Logger:%logger,Thread:%thread"/> <param name="Facility" value="Application"/> <param name="IncludeLocationInformation" value="false"/> <param name="ConversionPattern" value="%message%n%exception%n"/> </layout> </appender>

However Gelf4Net.HttpAppender works with same Graylog version - 4.2.5 and following config.

<appender name="gelfAppender" type="Gelf4Net.Appender.AsyncGelfHttpAppender, Gelf4Net.HttpAppender"> <url value="http://127.0.0.1:12201/gelf" /> <bufferSize value="2000" /> <threads value="2" /> <layout type="Gelf4Net.Layout.GelfLayout, Gelf4Net.Core"> <param name="AdditionalFields" value="Logger:%logger,Thread:%thread"/> <param name="Facility" value="Application"/> <param name="IncludeLocationInformation" value="false"/> <param name="ConversionPattern" value="%message%n%exception%n"/> <param name="ConversionPattern" value="[%t] %c{1} - %m" /> </layout> </appender>

Is there incompatibility of UdpAppender with Graylog 4?
Thanks.

Runtime errors (using JSNLog)

Hi,

I'm having some problems with Gelf4Net. I'm using it with JSNLog in a MVC project targeting 4.5. I have also created a class that extends the GelfUdpAppender to reformat JSNLog messages.

In Gelf4Net.UdpAppender (1.0.0.6) it gives me the following error at runtime with the log4net debugging:
log4net:ERROR Could not create Appender [GelfUdpAppender] of type [Gelf4net.Appender.GelfUdpAppender, Gelf4net]. Reported error follows. System.IO.FileNotFoundException: Could not load file or assembly 'Gelf4net' or one of its dependencies. The system cannot find the file specified. File name: 'Gelf4net' at System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMarkHandle stackMark, IntPtr pPrivHostBinder, Boolean loadTypeFromPartialName, ObjectHandleOnStack type) at System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean loadTypeFromPartialName) at System.RuntimeType.GetType(String typeName, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark) at System.Type.GetType(String typeName, Boolean throwOnError, Boolean ignoreCase) at log4net.Util.SystemInfo.GetTypeFromString(Assembly relativeAssembly, String typeName, Boolean throwOnError, Boolean ignoreCase) at log4net.Util.SystemInfo.GetTypeFromString(String typeName, Boolean throwOnError, Boolean ignoreCase) at log4net.Repository.Hierarchy.XmlHierarchyConfigurator.ParseAppender(XmlElement appenderElement)

In Gelf4Net (3.0.0.2) package it gives me:

log4net:ERROR Could not create Appender [GelfUdpAppender] of type [Gelf4net.Appender.GelfUdpAppender, Gelf4net]. Reported error follows. System.InvalidOperationException: An asynchronous operation cannot be started at this time. Asynchronous operations may only be started within an asynchronous handler or module or during certain events in the Page lifecycle. If this exception occurred while executing a Page, ensure that the Page is marked <%@ Page Async="true" %>. This exception may also indicate an attempt to call an "async void" method, which is generally unsupported within ASP.NET request processing. Instead, the asynchronous method should return a Task, and the caller should await it. at System.Web.AspNetSynchronizationContext.OperationStarted() at System.Runtime.CompilerServices.AsyncVoidMethodBuilder.Create() at Gelf4Net.Appender.GelfUdpAppender.ActivateOptions() at log4net.Repository.Hierarchy.XmlHierarchyConfigurator.ParseAppender(XmlElement appenderElement)

In Gelf4Net (3.0.0.1) it worked with the normal appender but when I used my own that extended yours it also gave me an error, similar to the first:
log4net:ERROR Could not create Appender [JsnGelfUdpAppender] of type [f.log4net.JsnGelfUdpAppender.JsnGelfUdpAppender, JsnGelfUdpAppender]. Reported error follows. System.TypeLoadException: Could not load type 'Gelf4Net.Appender.GelfUdpAppender' from assembly 'Gelf4Net, Version=3.0.0.1, Culture=neutral, PublicKeyToken=null'. at System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMarkHandle stackMark, IntPtr pPrivHostBinder, Boolean loadTypeFromPartialName, ObjectHandleOnStack type) at System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean loadTypeFromPartialName) at System.RuntimeType.GetType(String typeName, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark) at System.Type.GetType(String typeName, Boolean throwOnError, Boolean ignoreCase) at log4net.Util.SystemInfo.GetTypeFromString(Assembly relativeAssembly, String typeName, Boolean throwOnError, Boolean ignoreCase) at log4net.Util.SystemInfo.GetTypeFromString(String typeName, Boolean throwOnError, Boolean ignoreCase) at log4net.Repository.Hierarchy.XmlHierarchyConfigurator.ParseAppender(XmlElement appenderElement)

In Gelf4net/Gelf4NetAppender v 1.2.11.8 it works both on its own and with my extended class.

Kind regards,
Peter

Inheritance from assembly Gelf4Net from nuget.

Hello!
When I try to inherit from GelfAmqpAppender class I receive an error:
Argument 1: cannot convert from 'RabbitMQ.Client.IConnection [..\packages\Gelf4Net.2.0.3.16\lib\net40\Gelf4Net.dll]' to 'RabbitMQ.Client.IConnection [..\packages\RabbitMQ.Client.3.6.4\lib\net45\RabbitMQ.Client.dll]'

Error appears only when I use package from nuget, if I build assembly from source code - everything is ok.
Is it because RabbitMQ is merged into your assembly, am I right?

Thank you for gelf4net.

gelf http Async DoAppend slow

Hello,

Using Gelf http Async, with DoAppend.
Even if it's meant to be async, submitting 50K loggingeventdata through doappend is quite slow, around 10 minutes.
I tried to play with number of threads and buffersize, but it doesn't look to change anything in speed.

Any clue ?

Thanks in advance,

Dependencies not added

Hi,
We observe a strange behavior with gelf4Net dependencies.
We compile a standard Net Framework (V 4.52) application with Visual Studio 2013 and dependencies libraries are copied in bin directory. (Eg. Newtonsoft.Json.dll)

We compile same application with Visual Studio 2019 Msbuild (v 16.7) and dependencies libraries not are copied in bin directory. (Eg. Newtonsoft.Json.dll)

Inspecting package we found that .nuspec have this configuration:

So we suspect that new version of MsBuild v 16.7 does not copy necessary libraries in output folder and gelf appender not work!
Could you confirm this behavior, please? If so, we need add manually necessary dependency?
Thank you.

Gelf4Net.UdpAppender dll is not signed

Dll is not signed, which makes loading it fails
"Assembly with a strong name is required. HRESULT : 0x80131044"
(translated from french).

I can sign it with my cert, but would have todo it again after each update.

Thanks in advance for your help

ObjectDisposedException crashes out App Pool when used in ASP.NET

Hello and greetings!

I'm using gelf4net in an ASP.NET MVC application, hosted on AWS Elastic Beanstalk.

The App Pool crashes out almost immediately after the application starts running, with the following exception in the Windows Event Log:

Description: The process was terminated due to an unhandled exception.
Exception Info: System.ObjectDisposedException
Stack:
   at System.Net.Sockets.UdpClient.EndSend(System.IAsyncResult)
   at gelf4net.Appender.GelfUdpAppender.SendCallback(System.IAsyncResult)
   at System.Net.LazyAsyncResult.Complete(IntPtr)
   at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
   at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
   at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
   at System.Net.ContextAwareResult.Complete(IntPtr)
   at System.Net.Sockets.BaseOverlappedAsyncResult.CompletionPortCallback(UInt32, UInt32, System.Threading.NativeOverlapped*)
   at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32, UInt32, System.Threading.NativeOverlapped*)

I'm fairly confident that the exception occurs on this line: https://github.com/jjchiw/gelf4net/blob/master/src/Gelf4net/Appender/GelfUdpAppender.cs#L100

I'm wondering why the exception occurs though, since if it was a network connection loss I'd not expect an ObjectDisposedException.

Edit: After having consulted MSDN, it seems this exception gets thrown when the connection is closed.

Since this exception occurs in a thread not directly managed by IIS, it crashes out the worker process, sending the server into a permanent 503 state, until it's restarted by some means.

This is my configuration:

  <log4net>
    <appender name="GelfUdpAppender" type="Gelf4net.Appender.GelfUdpAppender, Gelf4net">
      <remoteAddress value="172.31.41.121" />
      <remotePort value="12201" />
      <layout type="Gelf4net.Layout.GelfLayout, Gelf4net">
        <param name="AdditionalFields" value="app:bridge,version:1.0,Level:%level" />
        <param name="Facility" value="bridge" />
        <param name="IncludeLocationInformation" value="true" />
        <!-- Sets the full_message and short_message to the specified pattern-->
        <param name="ConversionPattern" value="[%t] %c{1} - %m" />
      </layout>
    </appender>
    <root>
      <level value="ALL" />
      <appender-ref ref="GelfUdpAppender" />
    </root>
  </log4net>

I call log4net.Config.XmlConfigurator.Configure(); once in Application_Start(), and then use the logger like this:

var gelfLog = LogManager.GetLogger("bridge");
ThreadContext.Properties["Application"] = "blabla";
ThreadContext.Properties["SubUserID"] = 33;
ThreadContext.Properties["UserID"] = 11;

gelfLog.Info("SomeLogmessage");

The logging works - I'm getting messages in greylog up to the point where it crashes out. Any input?

Does not load using log4net 1.2.13.0

Gelf4net v2.0.3.1 referenced log4net 1.2.13.0 and worked fine.
Gelf4net v2.0.3.7 references log4net 1.2.11.0 and thus will not load against 1.2.13.0

Check the LoggingEvent.RenderedMessage property as well if MessageObject is null

Hello,

In log4net a new LoggingEvent object can be constructed using the LoggingEventData struct:

LoggingEventData loggingEventData = new LoggingEventData();
loggingEventData.Message = "Here is a short message";
//other properties are also set, ignored here
LoggingEvent loggingEvent = new LoggingEvent(loggingEventData);

Strangely enough the MessageObject property of LoggingEvent will be null, whereas the RenderedMessage property will be set to "Here is a short message".

Then in the AddLoggingEventToMessage method of GelfLayout (https://github.com/jjchiw/gelf4net/blob/master/src/Gelf4net/Layout/GelfLayout.cs , line 144) the code only checks the MessageObject property of LoggingEvent. If that is null then we pass a null message to Graylog.

I think it would make sense to check the RenderedMessage property as well. If MessageObject is null but RenderedMessage is not an empty string then gelfMessage.FullMessage should be populated with that value.

Thanks and best regards,
Andras Nemes

AMQP appender brings down IIS W3WP.exe

If you configure the AMQP appender incorrectly (e.g. change to a non-existent host like , the appender throws an exception that brings down W3WP.exe.

This happens here in GelfAmqpAppender.cs:
protected override void OnClose()
{
Channel.Close();
Channel.Dispose();
Connection.Close();
Connection.Dispose();
}

If you change this code as follows, the problem goes away:
protected override void OnClose()
{
if (Channel != null)
{
Channel.Close();
Channel.Dispose();
}
if (Connection != null)
{
Connection.Close();
Connection.Dispose();
}
}

So, either Channel or Connection are null (not sure which).

Stack traces from the Windows application log, in order, are as follows:
001.txt
002.txt
003.txt

Problem sending message to Graylog2 in Azure from my PC

With no success, I am trying to send a simple message with the folowing lines to a Graylog 2.2.3 machine in Azure.

log4net.Config.XmlConfigurator.Configure();
log.Error("There was an error!");

My config is this
<appender name="GelfHttpAppender" type="Gelf4net.Appender.GelfHttpAppender, Gelf4Net.HttpAppender"> <url value="http://graylog.azure.com:8081/gelf" /> <layout type="Gelf4net.Layout.GelfLayout, Gelf4Net.HttpAppender">
<param name="AdditionalFields" value="app:GelfHttpAppender,version:1.0,Environment:Dev,Level:%level" />
<param name="Facility" value="RandomPhrases" />
<param name="IncludeLocationInformation" value="true" />
<!-- Sets the full_message and short_message to the specified pattern-->
<param name="ConversionPattern" value="[%t] %c{1} - %m" />
</layout>
</appender>

<root> <level value="ALL" /> <appender-ref ref="GelfHttpAppender" /> </root>

My GrayLog machine is on Azure and is basically the machine Appliance version 2.2.3 available here
https://packages.graylog2.org/appliances/ova

The .NET code is running from my dev PC. I'm at the point of trying to run in debug mode to step into Gel4net solution to see what's going on.

Any hints because I'm not shure what I'm look for.

Update: I tested from another Azure machine, same behavior. However I checked in fiddler and see not http call made to the adress I configured in the app.config.

Data in a wrong format in Graylog?

I have a simple installation of RabbitMQ with Graylog.

The configuration is:

<log4net name="log4netelk">
    <appender name="AsyncGelfAmqpAppender" type="Gelf4Net.Appender.AsyncGelfAmqpAppender, Gelf4Net.AmqpAppender">
      <remoteAddress value="localhost" />
      <remotePort value="5672" />
      <username value="admin" />
      <password value="password" />
      <virtualHost value="/" />
      <exchange value="log-messages" />
      <key value="#" />
      <layout type="Gelf4Net.Layout.GelfLayout, Gelf4Net.AmqpAppender">
        <param name="AdditionalFields" value="app:ElectionApplication,version:1.0,Level:%level" />
        <param name="Facility" value="RandomPhrases" />
        <param name="IncludeLocationInformation" value="true" />
        <param name="SendTimeStampAsString" value="false" />
        <!-- Sets the full_message and short_message to the specified pattern-->
        <!--        <param name="ConversionPattern" value="[%t] %c{1} - %m" />-->
      </layout>
    </appender>
    <appender name="TraceAppender" type="log4net.Appender.TraceAppender">
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%-4timestamp [%thread] %-5level %logger %message%newline" />
      </layout>
    </appender>
    <root>
      <level value="ALL" />
      <appender-ref ref="AsyncGelfAmqpAppender" />
      <appender-ref ref="TraceAppender" />
    </root>
  </log4net>

But the data coming in graylog:
message
����Q�N�@������^�ҭ���T �+4 � y�Gٰ�mv��b�w�R�1ē��7o&3o?��B�5d\p{pb��@�T�n4�4�����k�)flaP��r����cs���26�RU�d=�� �?�[������������˕�$���t������V��7r�s��2�N1��_ަ���s:�FA�
ܣ��}r�D�Q�[^��P�Ք�4��~�Fn��Կ�O;��Z��ѹ^+LT���@��]��������|ԝ��*���q�[��W�j���ډ�%~��{�G#B����AD�Wr����f�u3�����-���� �6҇��<k�7.�k�����'���������ab

Any idea what im doing wrong?

where are params and their defaults documented

what is the default value for SendTimeStampAsString? My new Graylog instances is complaining

GELF message (received from host:port) has invalid "timestamp": 1661540192.05392 (type: STRING)

where are the the params documented?

Error loading configuration: Gelf4Net not found

Appender configuration is incorrect since I update to Gelf4net 1.0.0.17.

With the configuration

"Gelf4Net file is not found"

I had to update ther configuration to to:

Now it's OK but the documentation does not seem up-to-date.

Trying to do simple logging from a WinForms application

I looked at the code of the SimpleConsoleApplicationHttpPackage console app. Pretty simple and it works with a local (in virtual box) Graylog2 VM (for now). However I tried the three lines of code which seem to matter and no message is sent.

class Program
{
protected static readonly ILog log = LogManager.GetLogger(typeof(Program));
static void Main(string[] args)
{
log4net.Config.XmlConfigurator.Configure();
Console.WriteLine("Write a sentence, q to quit");
var text = Console.ReadLine();
while(text != "q")
{
log.Debug(String.Format("Randomizer Sentence: {0}", text));
Console.WriteLine("Sent {0}", text);
text = Console.ReadLine();
Console.WriteLine("Sent");
}
}
}

The configs are the same. My code is as follow.

private void btnError_Click(object sender, EventArgs e)
{
GLAppender.SendMessage(txtMessage.Text);
}

class GLAppender
{
    protected static readonly ILog log = LogManager.GetLogger(typeof(Program));
    public static void SendMessage(string message)
    {
        log4net.Config.XmlConfigurator.Configure();
        log.Debug(message);
    } 
}

UPDATE: Now I have the simplest code I can, still nothing is sent :-(. It's almost a copy paste from the example project.

public partial class Form1 : Form
{
protected static readonly ILog log = LogManager.GetLogger(typeof(Program));

    public Form1()
    {
        InitializeComponent();
    }

    private void btnError_Click(object sender, EventArgs e)
    {
        log4net.Config.XmlConfigurator.Configure();
        log.Debug(txtMessage.Text);
    }
    
}

TCP Support

Is there a way to use TCP instead of UDP?

IIS Application pool Crashed During APP Pool Recycle and apparently Gelf was the culprit

We use Graylog to log all the Database calls in our application. We had the IIS App Pool recycle scheduled at 3AM in the morning. During the Recycle, the IIS failed to start with following logs in System Event log

An unhandled exception occurred and the process was terminated. Application ID: /LM/W3SVC/2/ROOT Process ID: 4924 Exception: System.ObjectDisposedException Message: Cannot access a disposed object. Object name: 'System.Net.Sockets.Socket'. StackTrace: at System.Net.Sockets.Socket.EndSendTo(IAsyncResult asyncResult) at System.Net.Sockets.UdpClient.EndSend(IAsyncResult asyncResult) at gelf4net.Appender.GelfUdpAppender.SendCallback(IAsyncResult ar) at System.Net.LazyAsyncResult.Complete(IntPtr userToken) at System.Net.ContextAwareResult.CompleteCallback(Object state) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Net.ContextAwareResult.Complete(IntPtr userToken) at System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken) at System.Net.LazyAsyncResult.InvokeCallback(Object result) at System.Net.Sockets.BaseOverlappedAsyncResult.CompletionPortCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped) at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)

An unhandled exception occurred and the process was terminated.

Application ID: /LM/W3SVC/2/ROOT

Process ID: 4924

Exception: System.ObjectDisposedException

Message: Cannot access a disposed object.
Object name: 'System.Net.Sockets.Socket'.

StackTrace:    at System.Net.Sockets.Socket.EndSendTo(IAsyncResult asyncResult)
   at System.Net.Sockets.UdpClient.EndSend(IAsyncResult asyncResult)
   at gelf4net.Appender.GelfUdpAppender.SendCallback(IAsyncResult ar)
   at System.Net.LazyAsyncResult.Complete(IntPtr userToken)
   at System.Net.ContextAwareResult.CompleteCallback(Object state)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Net.ContextAwareResult.Complete(IntPtr userToken)
   at System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken)
   at System.Net.LazyAsyncResult.InvokeCallback(Object result)
   at System.Net.Sockets.BaseOverlappedAsyncResult.CompletionPortCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
   at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)

The number of message being sent to Graylog was pretty high as it sent 20lac messages in the span of 17 hours (which is too much). When I looked at GelfUdpAppender, I think what might have happened is the client object was recycled before the EndSend() is called. But I am not sure about it.

Following is how we are creating logger. We created the static instance of the logger

 static readonly ILog log = LogManager.GetLogger(typeof(LogLiveSps));

And I am logging the error as below

log.Error(sb.ToString());

Do let me know if my assumption is correct. With this effort we have memached most of the DB calls, but my worry is that, if I enable graylog again, it should not crash the app pool on live site during recycle.

HTTP Appender

We have applications deployed in networks outside the network the Graylog instance is deployed into. We also don't have control over the firewall rules. The only real option seems to be logging via HTTP(s) as these ports are guaranteed to be open.

Are there any plans to add a GelfHTTPAppender? Do you see any issues with this?

GelfUdpAppender.GenerateMessageId() generates collisioning IDs

Hello, the code below will generate identical message ids when called twice in a hundredth of a millisecond. On our application that happens.

public static string GenerateMessageId()
{
    var md5String = String.Join("", MD5.Create().ComputeHash(Encoding.Default.GetBytes(Environment.MachineName)).Select(it => it.ToString("x2")).ToArray<string>());
    var sb = new StringBuilder();
    var t = DateTime.Now.Ticks % 1000000000;
    var s = String.Format("{0}{1}", md5String.Substring(0, 10), md5String.Substring(20, 10));
    var r = Random.Next(10000000).ToString("00000000");

    sb.Append(t); // <== this is already 10 chars long
    sb.Append(s); // this is trimmed out by substring
    sb.Append(r); // this is also trimmed out by substring

    //Message ID: 8 bytes 
    return sb.ToString().Substring(0, MaxHeaderSize);
}

Of the 3 appended variables (t, s and r) only the first 8 chars of t are kept.
I tested with the code below:

void Main()
{
    for (int i=1; i<10; i++) {
        Console.WriteLine(GenerateMessageId());
    }
}

// OUTPUT:
// 84128103
// 84128103
// 84128103
// 84128589
// 84128589
// 84128589
// 84129093
// 84129093
// 84129093

Gelf4Net HttpAppender causes InvalidOperationException

My ASP.NET WepAPI application is making use of the HttpAppender for logging.

The issue I am encountering is that on two of my web methods, the calls result in:

[InvalidOperationException]: An asynchronous module or handler completed while an asynchronous operation was still pending.

which is related to this issue: https://stackoverflow.com/questions/15060214/web-api-httpclient-an-asynchronous-module-or-handler-completed-while-an-async

And can be seen here: GelfHttpAppender.cs

The commented out code would possibly resolve the issue since I don't think the AppenderSkeleton supports Append as returning a Task.

Trouble with .NetCore

Hi,
I would like to send my log message to GrayLog and using a common library for .NEt Framework and for .NetCore.
Just for testing i am showing logging message to console. For .Net Framework works fine but for .NetCore i do not get any output.

My config file is

<?xml version="1.0" encoding="utf-8" ?>
<log4net>
  <appender name="Console"
            type="log4net.Appender.ConsoleAppender">
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="app:%property{AppName},version:2.0,Environment:DEV,Level:%level: %message%newline" />
    </layout>
  </appender>

  <logger name="GelfUdpAppenderNA">
    <level value="ALL" />
    <appender-ref ref="Console" />
  </logger>
</log4net>

And in my code i check if my app is a .NET Core or not .

FileInfo fi = new FileInfo("log4net.xml");
if (OSUtils.IsNetCoreFramework())
{
    var logRepository = LogManager.GetRepository(Assembly.GetEntryAssembly());
    XmlConfigurator.Configure(logRepository, fi);
}
else
{
    XmlConfigurator.Configure(fi);
}

ILog iLog = LogManager.GetLogger("GelfUdpAppenderNA");
switch (eventType)
{
	case EventType.Debug:
		iLog.Debug(logMessage);
		break;

	case EventType.Information:
		iLog.Info(logMessage);
		break;

	case EventType.Error:
		iLog.Error(logMessage);
		break;
}

Any hint for solve this ?
TIA,
Yamil

could not create appender

Hello,

I'm using the GelfAmqpAppender but I do not want my messages to be GZip before being sent to RabbitMQ.

I changed the GzipMessage function to remove the GZip. To recomile without error and I replace the DLL Gelf4Net.dll in my solution by my version.

Now, I have this error message "could not create appender".

log4net:ERROR Could not create Appender [GelfAmqpAppender] of type [Gelf4Net.Appender.GelfAmqpAppender, Gelf4Net]. Reported error follows.
System.MissingFieldException: Champ introuvable : 'RabbitMQ.Client.ConnectionFactory.HostName'.
à Gelf4Net.Appender.GelfAmqpAppender.InitializeConnectionFactory()
à Gelf4Net.Appender.GelfAmqpAppender.ActivateOptions()
à log4net.Repository.Hierarchy.XmlHierarchyConfigurator.ParseAppender(XmlElement appenderElement)
log4net:ERROR Appender named [GelfAmqpAppender] not found.

Could you help me ?

thank you very much

Messages not sent and Context Variables mixed (Async)

Hi!

We were doing some load testing when we realized that there was a significant amount of messages lost.
After discarding the network, we have doing some sample code to serve as sort of test using only localhost. The test contains a dummy message parser to be able to conciliate the results.

We found that 60% of the messages don't arrive and also we detected that the LogicalThreadContext was being mixed between messages. I've tested both sync and sync implementations of the appender.

Am I missing something? wrong configuration?

Log4netplayground.zip

Web app hang from thread lock after AsyncGelfUdpAppender.Append()

Hi,
We've found our web application hang after started using gelf4net on some of our production server.
The problem comes a few hour after application start. We decided to dump memory while it hang for analysis and here is what we found.

------Type of Analysis Performed Hang Analysis------------
Machine Name
Operating System Windows Server 2008 R2Service Pack 1
Number Of Processors:
Process ID 9856
Process Image
Command Line
System Up-Time 100 day(s) 14:55:06
Process Up-Time 02:54:09
Processor Type X64
Process Bitness 64-Bit

------------- .NET Threads Summary --------------
Total Threads: 569
Running Threads: 569
Idle Threads: 0
Max Threads: 32767
Min Threads: 120


82.32% of threads blocked (568 threads)
Look at the callstack of thread 143 to see why that thread id waiting on and why it is not releasing the lock.

--------- Stacktrace of thread no. 143 ---------------

[[HelperMethodFrame_1OBJ] (System.Threading.Monitor.ObjWait)] System.Threading.Monitor.ObjWait(Boolean, Int32, System.Object) 
mscorlib_ni!System.Threading.SemaphoreSlim.WaitUntilCountOrTimeout(Int32, UInt32, System.Threading.CancellationToken)+68 
mscorlib_ni!System.Threading.SemaphoreSlim.Wait(Int32, System.Threading.CancellationToken)+149 
System_ni!System.Collections.Concurrent.BlockingCollection`1[[System.__Canon, mscorlib]].TryAddWithNoTimeValidation(System.__Canon, Int32, System.Threading.CancellationToken)+104 
Gelf4Net.Appender.AsyncGelfUdpAppender.Append(log4net.Core.LoggingEvent)+61 
log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent)+fa 
log4net.Util.AppenderAttachedImpl.AppendLoopOnAppenders(log4net.Core.LoggingEvent)+a6 
log4net.Repository.Hierarchy.Logger.CallAppenders(log4net.Core.LoggingEvent)+70 
log4net.Repository.Hierarchy.Logger.Log(System.Type, log4net.Core.Level, System.Object, System.Exception)+66 
log4net.Core.LogImpl.Info(System.Object)+47 

----------- Many threads that were blocked by 143 were on Enter lock state ----------------

[[HelperMethodFrame] (System.Threading.Monitor.Enter)] System.Threading.Monitor.Enter(System.Object) 
log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent)+45 
log4net.Util.AppenderAttachedImpl.AppendLoopOnAppenders(log4net.Core.LoggingEvent)+a6 
log4net.Repository.Hierarchy.Logger.CallAppenders(log4net.Core.LoggingEvent)+70 
log4net.Repository.Hierarchy.Logger.Log(System.Type, log4net.Core.Level, System.Object, System.Exception)+66 
log4net.Core.LogImpl.Info(System.Object)+47 

---------- Here is our appender configuration -------

<appender name="AsyncGelfUdpAppender" type="Gelf4Net.Appender.AsyncGelfUdpAppender, Gelf4Net">
		<remoteAddress value="10.94.24.104" />
		<remotePort value="12201" />
		<bufferSize value="200" />
		<threads value="2" />
		<layout type="Gelf4Net.Layout.GelfLayout, Gelf4Net">
			<param name="AdditionalFields" value="App:Web,Version:2.0,Level:%level,Exception:%exception" />
			<param name="Facility" value="OurApp" />
			<param name="IncludeLocationInformation" value="false" />
			<param name="SendTimeStampAsString" value="false"/>
			<param name="LogStackTraceFromMessage" value="true" />

		</layout>
</appender>

Is there anything wrong on our configuration that cause thread block?
Any idea or suggestion would be appreciated.

Thank you

wrong line number type /deprecated

Hi,

Gelf4Net sends field line number as string. The GELF standard describes it as number. Unfurtunatly log4net seems to fill sometimes the internal variable with an '?'. This end up with an index Error on Graylog Server.

additionally the field line,file and facility is marked as deprecated.

TCP with SSL/TLS support

Are there any plans to create a version with TCP and SSL/TLS support? If not, would you consider to merge a PR if I were to create one with this?

AsyncGelfHttpAppender error in OnClose() method.

When setting an invalid URL on the appender, the application crashes when trying to log with the following error:

https://i.imgur.com/b50Zegs.png

with the following appender config:

https://i.imgur.com/ApQL4Xu.png

Looking through the code, the OnClose of the appender has the _sender property set to null since the

base.ActivateOptions();

fails.

could probably fix this by just putting the _sender initialization before callind the base.ActivateOptions in the AsyncGelfHttpAppender's own ActivateOptions.

Gelf always write a warning message to stdout after specified %level to in additionalfields

Hi,
We've found the following line of message has been written down to stdout all the time. I'm not sure for what's wrong with our level's configuration.

------------------------STDOUT-------------
log4net: Converter [level] Option [] Format [min=-1,max=2147483647,leftAlign=False]
log4net: Converter [level] Option [] Format [min=-1,max=2147483647,leftAlign=False]
log4net: Converter [level] Option [] Format [min=-1,max=2147483647,leftAlign=False]

------------- Appender Configuration -----------

<appender name="AsyncGelfHttpAppender" type="Gelf4Net.Appender.AsyncGelfHttpAppender, Gelf4Net">
		<url value="http://10.94.24.104:12201/gelf" />
		<bufferSize value="200" />
		<threads value="2" />
		<layout type="Gelf4Net.Layout.GelfLayout, Gelf4Net">
			<param name="AdditionalFields" value="App:Web,Version:2.0,Level:%level" />
			<param name="Facility" value="webapp" />
			<param name="IncludeLocationInformation" value="false" />
			<param name="LogStackTraceFromMessage" value="true" />
			<param name="SendTimeStampAsString" value="false" />
		</layout>
	</appender>

Could you please suggest for how to prevent these line of message?
Thank you very much,

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.