Git Product home page Git Product logo

log4j-s3-search's Introduction

log4j-s3-search

  • Log4j 1.x is no longer supported. If you're still using Log4j 1.x, PLEASE consider upgrading to Log4j 2.x. Log4j 1.x is deprecated, and there are vulnerabilities with it that nobody will fix.
    • If you REALLY need to continue using Log4j, you may use release 3.7.0. But really: upgrade to Log4j2 for your own sake.

image

A Log4j appender implementation that will collect log events into a staging buffer up to a configured size to then publish to external stores such as:

All external stores above are optional (although to be of any use at least one should be used). If no configuration is found for S3, for instance, the appender will not attempt to publish to S3. Likewise, if there is not configuration for Apache Solr, the appender will not attempt to publish to Solr.

Prerequisites

The packages in MVN Repo should work as long as you're on the correct Java version (see below).

Release / tag JSDK version
2.x and earlier Java SDK (JDK) 8
5.2.1 and earlier Java SDK (JDK) 11
5.2.2+ OpenJDK 21

Packages

The project is broken up into several packages:

  • appender-core -- Log4j version-agnostic logic that deals with maintaining the log staging buffer and publishing to external stores. However, you typically do not need to explicitly depend on this since one of the following will.
  • appender-log4j2 -- Log4j 2.x binding code that, together with appender-core, will allow client code to use the project with Log4j 2.x.

Usage

  • Add appender-log4j2 into your dependencies. (See appender-log4j2-sample from log4j-s3-search-samples for an example of how it's done.)

Maven Dependencies

Please substitute in the latest version in your case (so I don't have to keep updating this README.md).

<dependency>
    <groupId>com.therealvan</groupId>
    <artifactId>appender-log4j2</artifactId>
    <version>4.0.0</version>
</dependency>

Obsolete versions

Please ignore the non-semver versions 2.0 and 0.3.0.

Running the sample programs

Please consult the log4j-s3-search-samples project for sample programs using this library for both Log4j and Log4j2.

Configuration

General

In addition to the typical appender configuration (such as layout, Threshold, etc.), these common properties control the appender in general:

  • stagingBufferSize -- the number of entries to collect for a batch before publishing (default is 2000).
  • stagingBufferAge -- (optional) if specified, the number of minutes to wait before publishing a batch. If used, this parameter will override the condition set by stagingBufferSize. The value must be >= 1.
  • hostName -- (optional) a string to use to indicate where this log comes from. If this is not configured, by default it uses the host name where the logger is run. When set, this cannot be a blank string, or it will be ignored.
  • tags -- (optional) comma-separated tokens to associate to the log entries (used mainly for search filtering). Examples:
    • production,webserver
    • qa,database

DO NOT specify both stagingBufferSize and stagingBufferAge. Choose the option that works best for you. Because there is some overhead on preparing and upload of logs, if you specify too small a value for these parameters, the logger may not have enough time to do its work and eventually will cause your process to fail.

How small is too small? It really depends on how often your program logs. In general, I would suggest a minimum of 500 for stagingBufferSize and 60 seconds for stagingBufferAge.

A sample snippet from a sample log4j2.xml to publish whenever 10 events are collected:

<Configuration status="INFO">
  <Appenders>
    <Log4j2Appender name="Log4j2Appender">
      <PatternLayout pattern="%d{HH:mm:ss,SSS} [%t] %-5p %c{36} - %m%n"/>
      <verbose>false</verbose>

      <!-- Examples of optional tags to attach to entries (applicable only to SOLR & Elasticsearch)-->
      <tags>TEST,ONE,TWO;THREE</tags>

      <!-- Number of messages (lines of log) to buffer before publishing out -->
      <stagingBufferSize>10</stagingBufferSize>

      <s3Bucket>mybucket</s3Bucket>
      <s3Path>logs/exampleApplication2/</s3Path>
      <s3Region>us-west-2</s3Region>
      ...
      

or, if a time-based publishing policy is desired (e.g. publish every 15 minutes):

<Configuration status="INFO">
  <Appenders>
    <Log4j2Appender name="Log4j2Appender">
      ...

      <!-- Number of messages (lines of log) to buffer before publishing out -->
      <stagingBufferAge>15</stagingBufferAge>
      ...

S3

These properties (please use your own values) control how the logs will be stored in S3:

  • s3Bucket -- the S3 bucket to use. The logger will attempt to create this bucket if it doesn't already exist.
  • s3Path -- the path to the uploaded files (S3 key prefix under the hood)

These properties determine how to connect to S3:

  • s3Region -- the AWS region to use (e.g. "us-west-2").
  • s3ServiceEndpoint -- the service endpoint to use instead of the default.
  • s3SigningRegion -- the region to use for signing requests.

Use either:

  • s3Region or
  • s3ServiceEndpoint and s3SigningRegion

but not all three simultaneously. You will get an error from AWS if you use all three.

AWS credentials are required to interact with S3. NOTE that the recommended way of configuring the credentials is:

  1. using roles assigned to instance profiles (when working with EC2 instances) or
  2. creating a credentials file on the computer running the program as %USERPROFILE%\.aws\credentials (Windows) or ~/.aws/credentials (see https://docs.aws.amazon.com/sdk-for-java/v2/developer-guide/credentials.html#credentials-file-format)

If the above methods are not possible for your situation, these properties can also be overridden in the optional Log4j configuration:

  • s3AwsKey and s3AwsSecret -- access and secret keys.
  • s3AwsSessionToken -- session token for short-lived credentials.

When these properties are present in the configuration, they take precedence over the default sources in the credential chain as described earlier.

A sample snippet (with the optional s3AwsKey and s3AwsSecret properties set):

<Configuration status="INFO">
  <Appenders>
    <Log4j2Appender name="Log4j2Appender">
        ...
      <s3Bucket>mybucket</s3Bucket>
      <s3Path>logs/exampleApplication2/</s3Path>
      <s3Region>us-west-2</s3Region>
      <s3AwsKey>CMSADEFHASFHEUCBEOERUE</s3AwsKey>
      <s3AwsSecret>ASCNEJAERKE/SDJFHESNCFSKERTFSDFJESF</s3AwsSecret>
      ....

The final S3 key used in the bucket follows the format:

{s3Path}/yyyyMMddHH24mmss_{hostname}_{UUID w/ "-" stripped}

e.g.

logs/myApplication/20150327081000_localhost_6187f4043f2449ccb4cbd3a7930d1130

Content configurations

Azure Blob

These properties (please use your own values) control how the logs will be stored in Azure Blob Storage:

  • azureBlobContainer -- the storage container name.
  • azureBlobNamePrefix -- the prefix for the blob name.
  • azureBlobCompressionEnabled -- if set to "true," then contents will be GZIP'ed before publishing.
  • azureStorageConnectionString -- optional value for the connection string for connecting to Azure. See note below.
  • azureBlobNameGzSuffixEnabled -- if set to "true," then the blob name will have a .gz suffix when azureBlobCompressionEnabled is enabled. (If azureBlobCompressionEnabled is not "true," this is ignored.)
<Configuration status="INFO">
  <Appenders>
    <Log4j2Appender name="Log4j2Appender">
        ...
        <azureBlobContainer>my-container</azureBlobContainer>
        <azureBlobNamePrefix>logs/myApplication/</azureBlobNamePrefix>
        
        <!-- optional -->
        <azureBlobCompressionEnabled>false</azureBlobCompressionEnabled>
        <azureStorageConnectionString>DefaultEndpointsProtocol=https;AccountName=...;EndpointSuffix=core.windows.net</azureStorageConnectionString>

Just as the case of S3, the final blob name used in the container follows the format:

{azureBlobNamePrefix}/yyyyMMddHH24mmss_{hostname}_{UUID w/ "-" stripped}

e.g.

logs/myApplication/20150327081000_localhost_6187f4043f2449ccb4cbd3a7930d1130

Notes:

See Azure Storage connection strings for more info on connection strings.

Google Cloud Storage

These properties (please use your own values) control how the logs will be stored in GCP Storage service:

  • gcpStorageBucket -- the storage bucket name.
  • gcpStorageBlobNamePrefix -- the prefix for the blob name.
  • gcpStorageCompressionEnabled -- if set to "true," then contents will be GZIP'ed before publishing. The default is "false."
  • gcpStorageBlobNameGzSuffixEnabled -- if set to "true," then the blob name will have a .gz suffix when gcpStorageCompressionEnabled is enabled. (If gcpStorageCompressionEnabled is not "true," this is ignored.)

Just as in the case with AWS S3, there is an extensive authentication process and list of options. This tool will assume the running process has the necessary authentication setup done.

While working on this, for example, I downloaded my service account's JSON key file and set the environment variable GOOGLE_APPLICATION_CREDENTIALS to the full path to the file. This allowed my programs using the Store API to work without doing any specific authentication calls.

A sample snippet from log4j2.xml:

<Configuration status="INFO">
  <Appenders>
    <Log4j2Appender name="Log4j2Appender">
        ...
        <gcpStorageBucket>my-bucket</gcpStorageBucket>
        <gcpStorageBlobNamePrefix>logs/myApplication/</gcpStorageBlobNamePrefix>
        
        <!-- optional -->
        <gcpStorageCompressionEnabled>false</gcpStorageCompressionEnabled>

Just as the other cases, the final blob name used in the bucket follows the format:

{gcpStorageBlobNamePrefix}/yyyyMMddHH24mmss_{hostname}_{UUID w/ "-" stripped}

e.g.

logs/myApplication/20150327081000_localhost_6187f4043f2449ccb4cbd3a7930d1130

Advanced Cloud Storage Configuration

Dynamic Path/Prefix Pattern

Normally, static values are used for path/prefix for the cloud storage destination. An example is a file-path-like string:

logs/messages/myapp/

This will cause published logs to look like:

logs/message/myall/....

However, there is a limited support for template expansion (currently only the datetime). So it is possible to specify a path like:

logs/messages/%d{yyyy_MM_dd_HH_mm_ss}/myapp

The above will tell the cloud storage publishers to dynamically adjust the path/prefix for the destination of the blobs published using the same syntax used for PatternLayout.

An uploaded blob with the configuration above may look like:

logs/messages/2020_08_23_22_04_34/myapp/....

Note that, in the above example, the time at which the publish was done (e.g. 2020-08-23 10:04:34 PM) was dynamically injected into the path according to the pattern specified. As more logs are published, each publish will have a different path/prefix because each of these publishes will be done at different times.

Solr

There is only one property for Solr: the REST endpoint to the core/collection:

  • solrUrl -- the URL to core/collection

A sample snippet:

<Configuration status="INFO">
  <Appenders>
    <Log4j2Appender name="Log4j2Appender">
        ...
        <solrUrl>http://localhost:8983/solr/log-events/</solrUrl>

Elasticsearch

There are four properties for Elasticsearch, all but one are optional:

  • elasticsearchCluster -- the cluster name (default if "elasticsearch")

  • elasticsearchIndex -- the index in which to store the log data (default is "logindex")

  • elasticsearchType -- the type of a log data entry (default is "log")

  • elasticsearchHosts -- comma-delimited list of host:port values. There is no default; this property is required.

    The scheme/protocol is http:// by default, but you can override this by explicitly including it in the value (e.g. https://localhost:9200).

  • elasticSearchPublishHelperClass -- optional fully-qualified name of the class (on the runtime classpath, of course) implementing IElasticsearchPublishHelper that will perform publishing to Elasticsearch

<Configuration status="INFO">
  <Appenders>
    <Log4j2Appender name="Log4j2Appender">
        ...
        <elasticsearchCluster>elasticsearch</elasticsearchCluster>
        <elasticsearchIndex>logindex</elasticsearchIndex>
        <elasticsearchType>log</elasticsearchType>
        <elasticsearchHosts>elasticsearchHosts=localhost:9300</elasticsearchHosts>

Solr Integration

A new core should be created for the log events. The setting up of Apache Solr and the setting up of a core are outside the scope of this file. However, a sample template for a schema.xml that can be used is included in this repo as /misc/solr/schema.xml.

Each log event will be indexed as a Solr document. The "id" property for each document will follow the format:

yyyyMMddHH24mmss_{host name}_{UUID w/ "-" stripped}-{host name}-{sequence}

e.g.

20150327081000_mycomputer_6187f4043f2449ccb4cbd3a7930d1130-mycomputer-0000000000000012

NOTE that this ID is formatted such that one can cross-reference a document to the S3 batch from which the corresponding log event can be found.

String id = solrDoc.getFieldValue("id").toString();
String s3Key = id.substring(0, id.indexOf("-"));

Elasticsearch Integration

A new index should be created for the log events. The setting up of Elasticsearch and the index are outside the scope of this file. However, a sample template for the index schema that can be used is included in this repo as /misc/elasticsearch/logindex.json. This schema should be installed before any log entries are added. A typical PUT to /<elasticsearch host>:9200/<index> with the body of the JSON should be sufficient.

Each log event will be indexed as a document. The "id" property for each document will follow the format:

yyyyMMddHH24mmss_{host name}_{UUID w/ "-" stripped}-{host name}-{sequence}

e.g.

20150327081000_mycomputer_6187f4043f2449ccb4cbd3a7930d1130-mycomputer-0000000000000012

NOTE that this ID is formatted such that one can cross-reference a document to the S3 batch from which the corresponding log event can be found.

String id = solrDoc.getFieldValue("id").toString();
String s3Key = id.substring(0, id.indexOf("-"));

Logging from log4j-s3-search

The appender and components of this library also logs events under the logger named "com.van.logging.VansLogger." To prevent logs of this logger from polluting the clients' logs, these logs will be ignored by the code (LoggingEventCache) when forwarding to various log publishers.

To see these logs (e.g. to debug), you can add a logger config to dump to console (or any other appender):

  <Appenders>
    <Console name="ConsoleAppender" target="SYSTEM_OUT">
      <PatternLayout pattern="%d{HH:mm:ss,SSS} [%t] %-5p %c{36} - %m%n"/>
    </Console>
    ...
  </Appenders>
  
  <Loggers>
    <Logger name="com.van.logging" level="debug" additivity="false">
      <AppenderRef ref="ConsoleAppender" />
    </Logger>
    ...
  </Loggers>
  ....

An example of this can be seen in the example repo log4j-s3-search-samples.

log4j-s3-search's People

Contributors

abhivijay89 avatar bluedenim avatar davinchia avatar dependabot[bot] avatar echojump avatar jdpgrailsdev avatar peeterskris avatar suqu13 avatar

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

log4j-s3-search's Issues

Support to get values for log4j2Appender configurations from environment variables

I run my apps in a containers where I have access to environment variables so that I can inject aws configurations, s3 configurations, s3 path and logFileName etc during startup in the log4j2.xml .

On checking the log4j2 official documentation I found "Log4j2 Lookups"
https://logging.apache.org/log4j/2.x/manual/lookups.html#environment-lookup

Do we have similar support, so that we can inject configurations like this in the Log4j2Appender??

These configurations are environment specific for my application

<Log4j2Appender name="Log4j2Appender">
			<PatternLayout pattern="%d{HH:mm:ss,SSS} [%t] %-5p %c{36} - %m%n"/>
			<verbose>false</verbose>
			<!--  Number of messages (lines of log) to buffer before publishing out  -->
			<stagingBufferSize>$${env:LOG4J_BUFFER_SIZE}</stagingBufferSize>
			<!-- <stagingBufferAge>15</stagingBufferAge> -->
			<s3Bucket>$${env:S3_LOGGING_BUCKET}</s3Bucket>
			<s3Path>/api/logs/</s3Path>
			<s3PathStyleAccess>true</s3PathStyleAccess>
			<s3Compression>true</s3Compression>
			<s3AwsKey>$${env:AWS_ACCESS_KEY}</s3AwsKey>
			<s3AwsSecret>$${env:AWS_SECRET_KEY}</s3AwsSecret>
			<s3Region>$${env:AWS_REGION}</s3Region>
		</Log4j2Appender>

Reduce the amount of imported AWS SDK packages

Hi,
We are currently optimizing our imports in our projects and happen to notice that your package seem to import the whole AWS 1.0 SDK (com.amazonaws.aws-java-sdk). Since this will import the whole SDK to the project, could you maybe consider only importing the needed S3 package (com.amazonaws.aws-java-sdk-s3)?

Extra end of line added when CsvParameterLayout is used

Hi. I'm using CsvParameterLayout to wite data in CSV format.
My config looks like:

<Log4j2Appender name="s3Appender">
    <CsvParameterLayout delimiter=","/>
    <verbose>false</verbose>

    <stagingBufferAge>1</stagingBufferAge>
    <s3Bucket>bucket</s3Bucket>
    <s3Path>path/</s3Path>

    <s3Region>us-east-1</s3Region>
</Log4j2Appender>

And I call logger like this:

logger.info("Another round through the loop!","0","0","0")

I expect to see data insisde file in the next format:

0,0,0
0,0,0
0,0,0

But instead I see:

0,0,0

0,0,0

0,0,0

image
I tried RollingFile appender and it looks fine. Probably there is some \n appending when S3Appender store data.

Cannot end publish with com.van.logging.azure.BlobPublishHelper

Cannot end publish with com.van.logging.azure.BlobPublishHelper@6d6174be due to error: org.apache.logging.log4j.core.layout.PatternLayout.serialize(Lorg/apache/logging/log4j/core/LogEvent;Ljava/lang/StringBuilder;)V

public class PatternedPathAdjuster implements IStorageDestinationAdjuster {

    @Override
    public String adjustPath(String path) {
        String adjusted = path;
        if (StringUtils.isTruthy(path)) {
            // e.g. "%d{yyyy-MM-dd}"
            StringBuilder sb = new StringBuilder();
            PatternLayout layout = PatternLayout.newBuilder().withPattern(path).build();
            MutableLogEvent evt = new MutableLogEvent();
            evt.setTimeMillis(System.currentTimeMillis());
            layout.serialize(evt, sb);
            adjusted = sb.toString();
        }
        return adjusted;
    }

}

Getting Error in layout.serialize(evt, sb);

i am using Spring 1.5.22-Release
com.therealvan-appender-log4j2 - 2.8.4

@bluedenim Can you suggest on it

Append logs in S3 and provide a file name pattern for file Creation

Hi @bluedenim

I would like append logs to the S3 file which was created once the buffer limit was reached.
In my case the file was created when the buffer limit was reached first time. For next time file was not created or updated in S3.

So can you provide a way through which I can achieve the same.
Moreover I would want to provide file name pattern which should be followed while creating files in S3. Let me know if we can do that or not using any current properties.

S3 Configuration Documentation

Using:

log4j.appender.S3Appender.s3AccessKey=
log4j.appender.S3Appender.s3SecretKey=

Results in:

log4j:WARN No such property [s3SecretKey] in org.van.logging.log4j.S3LogAppender.
log4j:WARN No such property [s3AccessKey] in org.van.logging.log4j.S3LogAppender.

Instead I needed to use:

log4j.appender.S3Appender.s3AwsKey=
log4j.appender.S3Appender.s3AwsSecret=

Thread pool executer shutdown not being called.

Hi,

Thread pool shutdown in LoggingEventCache class is not been called during shutdown hook in Log4j2Appender class. This is causing thread leaks and Apache tomcat is not stopping when a stop command is been sent, every time I have to force kill the tomcat process.

Can you please update the shutdown hook to call LoggingEventCache .shutdown()

Refresh "s3Path" setting for S3Appender based on configuration

I had one question about the configuration I am trying to create date wise folders using the “s3Path” element:

logs/messages/${date:YYYY-MM-dd}

Also I have set the “monitorInterval” attribute at the root Configuration element so that log4j configuration gets refreshed ( as per log4j documentation)

But notice that the S3Path, once initialized, does not change unless the application is restarted. Is there anyway to refresh configuration once the monitorInterval has elapsed or by recognizing that value uses functions like ${date}

Thanks!

Elastic Search

Before making a pull request I thought I would ask if there's already full support for elastic search implemented in appender version 2.6? I tried to enabling the elastic search appender in log4j2.xml but it's ignoring my xml settings and using predefined default values. It does however seem to respect only the elasticsearchHosts element. The other three properties: elasticsearchCluster, elasticsearchIndex, elasticsearchType are always set to - type=log , index=logindex , cluster=elasticsearch. Also I noticed the elastic search library is 5.4.3 which is pretty much deprecated, I think it's up to 7.11 now. As a follow up I was able to get the appender working using es transport client 6.8 after 'overidding' a couple of classes and making some changes to set these properties in the Log4j2AppenderBuilder.java. Please let me know if you would like me to send a PR with updates. We also have a requirement to format the message as json in elasticsearch . I added some code for that as well, but my guess is that we would need another configuration property to indicate that the message is json. Thank you for a really fantastic library.

System out in S3PublishHelper.java

Appears between v3.1.2 and v3.2.0 a system out on line 102 of S3PublishHelper was left in. Can you consider removing this line or migrating to using a logger?

Option for time based log rotation

First of all thank you for this project. It is very helpful.

I was thinking of an option to rotate logs not just based on size but also based on time (hourly, daily etc)

So that would involve mainly the LoggingEventCache class, right?

Not using Conversion Pattern configuration

Hi you all!
First of all, thanks for this lib, it seems to work perfectly for what I needed.
Its just one thing I am having a hard time with: it seems not to be using conversionPattern config, so whenever files get uploaded to s3, they always use the same naming pattern. I am using the com.van.logging.log4j.Log4jAppender here and did a search throughout all the source code and seems that this property is never read anywhere. Am I missing something or indeed this property is not being currently used?

Flushing out remaining events in the cache on shutdown

Hi @bluedenim

Our app runs as a scheduled job. So, when the shutdown hook is triggered, I would like whatever are the remaining events in the cache to be published to s3 rather than depending on the cacheMonitor() rules at this stage (i.e. stagingBufferSize or stagingBufferAge). Since, the cacheMonitor() rules are checked before publishing the staging log on shutdown, the last few events of our log which are critical, are being missed to be sent to s3. Can you suggest what would be the best way to fix/handle this in the code?

Reference snippet of code: https://github.com/bluedenim/log4j-s3-search/blob/master/appender-log4j/src/main/java/com/van/logging/log4j/Log4jAppender.java#L320.L328

Call to Exception.printStackTrace() causes Log4j2 to split stacktrace logs

In com.van.logging.LoggingEventCache.publishEventsFromFile(...), there’s a call to t.printStackTrace() which causes Log4j2 to create a log entry per stacktrace element in the printed exception. That is because the underlying implementation of java.lang.Throwable.printStackTrace() prints to system error one line at a time. It would be preferable to log these exceptions using a Log4j2 logger so it automatically gets formatted correctly.

Role with Session Token

Hello,

My IAM role needs a session token along with key & secret key. Is it possible to define this in the properties?

While using the log4j2.xml configurations for Gcp bucket I am getting invalid attributes error

Hi,
For a java project I want to write its logs into gcp-StorageBucket while trying it using the following maven dependencies

-<dependency>
<groupId>com.therealvan</groupId>
<artifactId>appender-core</artifactId>
<version>2.6.0</version>
</dependency>


-<dependency>
<groupId>com.therealvan</groupId>
<artifactId>appender-log4j2</artifactId>
<version>2.6.0</version>
</dependency>

The error I am getting is :

2020-11-12 16:16:11,945 main ERROR Log4j2Appender contains invalid attributes "gcpStorageBucket", "gcpStorageBlobNamePrefix"

Adding the log4j.xml for further reference

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
        </Console>
        <RollingFile fileName="./logs/project.log"
                     filePattern="./logs/project_log-%d{MM-dd-yyyy}-%i.log"
                     name="A1">
            <PatternLayout>
                <Pattern>"%d{yyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"</Pattern>
            </PatternLayout>
            <Policies>
                <SizeBasedTriggeringPolicy size="1 GB"/>
            </Policies>
            <DefaultRolloverStrategy max="5"/>
        </RollingFile>
        <Log4j2Appender name="Log4j2Appender">
            <gcpStorageBucket>${env:GCP_STORAGE_BUCKET}</gcpStorageBucket>
            <gcpStorageBlobNamePrefix>logs/test</gcpStorageBlobNamePrefix>
            <gcpStorageCompressionEnabled>false</gcpStorageCompressionEnabled>
            <stagingBufferAge>60</stagingBufferAge>
            <PatternLayout pattern="%d{yyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n&quot;"/>
        </Log4j2Appender>
    </Appenders>
    <Loggers>
        <Root level="debug">
            <AppenderRef ref="A1"/>
            <AppenderRef ref="Console"/>
        </Root>
        <Logger level="debug" name="com.project_name" additivity="false">
            <AppenderRef ref="A1"/>
            <AppenderRef ref="Console"/>
            <AppenderRef ref="Log4j2Appender"/>
        </Logger>
    </Loggers>
</Configuration>


can you just brief a solution for it ,Thank you

Incorrect example configuration documentation

Unless i'm confusing the situation, there is an error in the documentation. Currently there is the following example for the log4j.properties file:
log4j.appender.S3Appender=org.van.logging.log4j.S3LogAppender
After some frustration in not being able to instantiate the class, I realized that the correct path to the class is this com.van.logging.log4j.Log4jAppender

Multiple files publishing with S3 location control

Hi,

I wonder if it is possible to store logs into multiple locations on S3. For example.
We have standard arguments like:

  • s3Bucket: my_bucket
  • s3Path: my_path

In the case, we will store logs to:

 s3://my_bucket/my_path/timestamp_host_cache 

(according to a composeNamespacedCacheName in BufferPublisher)

But I would like to add some kind of partitioning. In my process, it is important to isolate job and its log. So the desired output would look as an example below:

 s3://my_bucket/my_path/job=value1/timestamp_host_cache 
 s3://my_bucket/my_path/job=value2/timestamp_host_cache 
etc.

Where value1 and value2 are arguments which we put in runtime somehow.
I'm not quite sure how we accumulate log data and if a behavior I described is possible.
Any ideas?

Thanks!

Issues preventing logging to storage grid

2020-10-16 16:32:01,191 main ERROR Could not create plugin of type class com.van.logging.log4j2.Log4j2Appender for element Log4j2Appender: java.lang.RuntimeException: Cannot build appender due to errors java.lang.RuntimeException: Cannot build appender due to errors

at com.van.logging.log4j2.Log4j2AppenderBuilder.build(Log4j2AppenderBuilder.java:126)
at com.van.logging.log4j2.Log4j2AppenderBuilder.build(Log4j2AppenderBuilder.java:24)
at org.apache.logging.log4j.core.config.plugins.util.PluginBuilder.build(PluginBuilder.java:122)
at org.apache.logging.log4j.core.config.AbstractConfiguration.createPluginObject(AbstractConfiguration.java:964)
at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:904)
at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:896)
at org.apache.logging.log4j.core.config.AbstractConfiguration.doConfigure(AbstractConfiguration.java:514)
at org.apache.logging.log4j.core.config.AbstractConfiguration.initialize(AbstractConfiguration.java:238)
at org.apache.logging.log4j.core.config.AbstractConfiguration.start(AbstractConfiguration.java:250)
at org.apache.logging.log4j.core.LoggerContext.setConfiguration(LoggerContext.java:548)
at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:620)
at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:637)
at org.springframework.boot.logging.log4j2.Log4J2LoggingSystem.reinitialize(Log4J2LoggingSystem.java:188)
at org.springframework.boot.logging.AbstractLoggingSystem.initializeWithConventions(AbstractLoggingSystem.java:72)
at org.springframework.boot.logging.AbstractLoggingSystem.initialize(AbstractLoggingSystem.java:59)
at org.springframework.boot.logging.log4j2.Log4J2LoggingSystem.initialize(Log4J2LoggingSystem.java:144)
at org.springframework.boot.context.logging.LoggingApplicationListener.initializeSystem(LoggingApplicationListener.java:279)
at org.springframework.boot.context.logging.LoggingApplicationListener.initialize(LoggingApplicationListener.java:254)
at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationEnvironmentPreparedEvent(LoggingApplicationListener.java:219)
at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationEvent(LoggingApplicationListener.java:196)
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172)
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:127)
at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:75)
at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:53)
at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:340)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:304)
at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:139)
at com.batchexecutor.BatchExecutorApp.main(BatchExecutorApp.java:14)

Caused by: java.lang.IllegalStateException: LoggingEventCache already created. Only one per process.
at com.van.logging.LoggingEventCache.(LoggingEventCache.java:111)
at com.van.logging.log4j2.Log4j2AppenderBuilder.build(Log4j2AppenderBuilder.java:121)
... 29 more

2020-10-16 16:32:01,200 main ERROR Unable to invoke factory method in class com.van.logging.log4j2.Log4j2Appender for element Log4j2Appender: java.lang.IllegalStateException: No factory method found for class com.van.logging.log4j2.Log4j2Appender java.lang.IllegalStateException: No factory method found for class com.van.logging.log4j2.Log4j2Appender
at org.apache.logging.log4j.core.config.plugins.util.PluginBuilder.findFactoryMethod(PluginBuilder.java:234)
at org.apache.logging.log4j.core.config.plugins.util.PluginBuilder.build(PluginBuilder.java:134)
at org.apache.logging.log4j.core.config.AbstractConfiguration.createPluginObject(AbstractConfiguration.java:964)
at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:904)
at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:896)
at org.apache.logging.log4j.core.config.AbstractConfiguration.doConfigure(AbstractConfiguration.java:514)
at org.apache.logging.log4j.core.config.AbstractConfiguration.initialize(AbstractConfiguration.java:238)
at org.apache.logging.log4j.core.config.AbstractConfiguration.start(AbstractConfiguration.java:250)
at org.apache.logging.log4j.core.LoggerContext.setConfiguration(LoggerContext.java:548)
at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:620)
at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:637)
at org.springframework.boot.logging.log4j2.Log4J2LoggingSystem.reinitialize(Log4J2LoggingSystem.java:188)
at org.springframework.boot.logging.AbstractLoggingSystem.initializeWithConventions(AbstractLoggingSystem.java:72)
at org.springframework.boot.logging.AbstractLoggingSystem.initialize(AbstractLoggingSystem.java:59)
at org.springframework.boot.logging.log4j2.Log4J2LoggingSystem.initialize(Log4J2LoggingSystem.java:144)
at org.springframework.boot.context.logging.LoggingApplicationListener.initializeSystem(LoggingApplicationListener.java:279)
at org.springframework.boot.context.logging.LoggingApplicationListener.initialize(LoggingApplicationListener.java:254)
at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationEnvironmentPreparedEvent(LoggingApplicationListener.java:219)
at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationEvent(LoggingApplicationListener.java:196)
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172)
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:127)
at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:75)
at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:53)
at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:340)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:304)
at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:139)
at com.batchexecutor.BatchExecutorApp.main(BatchExecutorApp.java:14)

2020-10-16 16:32:01,207 main ERROR Null object returned for Log4j2Appender in Appenders.

I also get the following further down in the logs:
Cannot end publish with com.van.logging.aws.S3PublishHelper@3ce29a4b due to error: org.apache.logging.log4j.core.layout.PatternLayout.serialize(Lorg/apache/logging/log4j/core/LogEvent;Ljava/lang/StringBuilder;)V

Do you have any ideas?

Support AWS IRSA.

Hi @bluedenim !

Thanks again for the great plugin. We at Airbyte love this. I'm wondering if you know whether this plugin supports IRSA.

We have several OSS community members interested in getting this working: airbytehq/airbyte-platform#263. I'm not sure if IRSA works well with this plugin now, and I would prefer to contribute back than roll our own.

We are happy to take pointers & submit a contribution.

Thanks!

Cannot end publish with com.van.logging.aws.S3PublishHelper

Cannot end publish with com.van.logging.aws.S3PublishHelper@1655c3b1 due to error: org.apache.logging.log4j.core.layout.PatternLayout.serialize(Lorg/apache/logging/log4j/core/LogEvent;Ljava/lang/StringBuilder;)V

Earlier used 2.3.1 to publish logs to S3 bucket. Now upgraded to 3.3.0 and started seeing above issue

@bluedenim - Any suggestion or recommendation will he helpful?

Multipart S3 upload support

Is it possible to minimise number of S3 files being created for logs by using Multipart Upload somehow? since S3 doesn't allow direct concatenation of small files?

Feature request(s) to override default s3 path & allow ACLs

Hello @bluedenim,

I) Can we provide the flexibility of overriding the default s3 bucket path 'logs/' and allow upload of files/objects directly under the bucket? Currently, I see "log4j.appender.L4jAppender.s3Path" is a mandatory property - instead could we make this optional or allow empty value which allows publishing the files directly under the bucket along with the option of creating a custom directory structure too. We have a downstream system requirement which picks & processes files directly under a bucketname rather than following a custom directory structure. Raised a PR for the same, could you please review or suggest what would the most efficient way to achieve this?
PR: ##67

II) Also, could we add option of allowing s3 ACLs? Due to restrictions imposed on our end, we need to push an object as below:
PutObjectRequest por = new PutObjectRequest(bucket, key, file).withCannedAcl(CannedAccessControlList.BucketOwnerFullControl);
instead of:
PutObjectRequest por = new PutObjectRequest(bucket, key, file);
Reference: https://github.com/bluedenim/log4j-s3-search/blob/master/appender-core/src/main/java/com/van/logging/aws/S3PublishHelper.java#L90

Error processing element Log4j2Appender ([Appenders: null]): CLASS_NOT_FOUND

I have added the therealvan dependencies in my JAVA project pom.xml ,I have build the jar and ran the code,then I got the error

2020-11-20 14:48:54,581 main ERROR Error processing element Log4j2Appender ([Appenders: null]): CLASS_NOT_FOUND
2020-11-20 14:48:54,757 main ERROR Unable to locate appender "Log4j2Appender" for logger config ""
2020-11-20 14:48:54,758 main ERROR Unable to locate appender "Log4j2Appender" for logger config ""

I have used all the versions including the latest version 2.8.3

SSE support

Hi. I'm trying to upload logs to S3 bucket with SSE (server-side encryption).
But I get an access denied error (for buckets without SSE everything is fine).

In my projects (on Kotlin), I use code like this:

val objectMetadata = ObjectMetadata()
objectMetadata.setSSEAlgorithm(ObjectMetadata.AES_256_SERVER_SIDE_ENCRYPTION)
objectMetadata.setContentLength(content.length.toLong())

val putRequest = PutObjectRequest(targetBucketName,targetCsvS3Path, contentBytesStream, objectMetadata)
s3Client.putObject(putRequest)

However, I'm not sure how to apply it to your project.

LoggingEventCache shutdown hangs with <stagingBufferAge> set

Spark hangs indefinitely when 'stagingBufferAge' param is set. Observing this behaviour only when 'stagingBufferAge' is used but with "stagingBufferSize", it works perfectly fine.
Log snippet post shutdown hook trigger (hangs here):

LoggingEventCache: shutting down
LoggingEventCache: Executor service terminated within timeout: true
ExecutorService refused submitted task. Was shutDown() called?

Security dependencies bump

Hello,

Airbyte use your project for some things and our security tools are reporting you miss some security dependencies update, at least the Elasticsearch one (elasticsearch-rest-high-level-client), 7.11 is End Of Support since a month, and you should move to latest 7.X (7.17.6 at this time)

I have tried enabling dependabot on my fork of your project and it follows automatically this kind of upgrade, maybe you should investigate enabling it on yours ?

Thanks for your help in fixing this.

Importing log4j-s3-search in gradle is broken

It seems that the POM of the maven repository is broken.

Importing the libraries in gradle using following dependencies:

compile group: 'com.therealvan', name: 'appender-core', version: '2.1.0'
compile group: 'com.therealvan', name: 'appender-log4j2', version: '2.1.0'

Results in following error message from gradle when building the project:

> Task :compileJava FAILED
FAILURE: Build failed with an exception.

* What went wrong:
Could not resolve all files for configuration ':compileClasspath'.
> Could not resolve com.therealvan:appender-core:2.1.0.
  Required by:
      project :
   > Could not resolve com.therealvan:appender-core:2.1.0.
      > Could not parse POM https://repo.maven.apache.org/maven2/com/therealvan/appender-core/2.1.0/appender-core-2.1.0.pom
         > Could not find com.therealvan:log4j-s3-search:2.1.0.
> Could not resolve com.therealvan:appender-log4j2:2.1.0.
  Required by:
      project :
   > Could not resolve com.therealvan:appender-log4j2:2.1.0.
      > Could not parse POM https://repo.maven.apache.org/maven2/com/therealvan/appender-log4j2/2.1.0/appender-log4j2-2.1.0.pom
         > Could not find com.therealvan:log4j-s3-search:2.1.0.

Looking at the POMs, it seems that the parent configuration key is not right (there is no package "log4j-s3-search"):

<parent>
<groupId>com.therealvan</groupId>
<artifactId>log4j-s3-search</artifactId>
<version>2.1.0</version>
</parent>

Support Property Substitution on Path/Prefix.

Hi,

We are moving some of our architecture to the cloud and are hoping to use this adapter to do cloud storage agnostic log4j2 logging. This is the best alternative I've found so far with out of the box support for all the major cloud providers + more - pretty awesome!

This is our current logging configuration. As you can see, we make use of context variables to dynamically set the file path. The readme makes it seem like this isn't possible today - is that correct?

If not, I'm very happy to help implement this. Would love some guidance on how to go about doing this!

Thanks!

Minio support.

Supporting logging to Minio would make testing apps that use this logger much easier.

Not able to use jars directly as dependencies in another project

First of all, thanks for creating this awesome project with a common and useful use case.

The problem I am facing is I am not able to use the jars appender-log4j2 and appender-core directly by including them as dependencies in pom.xml of my project as it complains parent project (log4j-s3-search) not found. I guess the only way to use my project is to add it as one of the modules in your parent pom, create a project inside your project just like your sample projects and build the parent pom. This will change the directory structure of my project which in turn will effect everyone in my organization.

Is there any easier way to integrate your jars directly with my project?

AWS S3 - lack of data compression

I noticed that the s3Compression flag is not used within appender-log4j2. I suppose that it is omitted in the given method. Using config.setCompressionEnabled(s3Compression) will solve the problem.

I suggest also to add additional flag that cooperates with s3Comporession to give users choice to decide if they want to use .gz file extension or not. A lot of AWS resources, like Athena, work well with compressed files but their names have to contain the suffix.

features..

Hey, thanks for working on this. how feasible would it be to:

  • append logs to an existing file in S3
  • compress output before storing in S3
    cheers!

License Terms

Please can you clarify your license terms? We're looking to include this in our project, but need to tweak the version of the AWS api's used.

spark-submit hangs after successful job completion

Hi @bluedenim

When executing a job via Spark using the s3-log4j-appender implementation, spark-submit command seems to hang after successful job execution. The logs are getting pushed to s3 based on 'stagingBufferSize' or 'stagingBufferAge' at the intermediate stages of the job execution but hangs at the end after SparkContext gets stopped successfully. I need to manually invoke ctrl-c to terminate the spark-submit process & then it goes ahead and publishes the staging log once the shutdown hook gets triggered. Took a thread dump to troubleshoot and I see this:

"LoggingEventCache-publish-thread" #229 prio=5 os_prio=0 tid=0x00007f4315601800 nid=0x4df waiting on condition [0x00007f430c8fa000]
   java.lang.Thread.State: WAITING (parking)
	at sun.misc.Unsafe.park(Native Method)
	- parking to wait for  <0x00000002c014f9c0> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
	at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
	at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
	at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
	at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)

Can you help to check what maybe causing this & provide insights on how this could be fixed? Has it got to do anything with the changes we did to publish in the current thread itself when shutdown hook gets invoked...

Thread Count - keep increase

Thanks for the fantastic module, but after trying to implement it, thread count keeps increasing, do you have any ideas to handle this case? Thank you

Screenshot from 2021-09-15 13-46-50

I couldn't able to log the application log to the s3

I can successfully log the custom logging into the s3 whereas i couldn't log the application log like spring boot log into s3. I couldn't find the s3 access key secret key terms in log4j2.xml how can i enable s3 in log4j2 sample without giving access key secret key.

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.