89
89
* @author Stephen Oakey
90
90
* @author Dominique Villard
91
91
* @author Nicolas Ristock
92
+ * @author Eugene Gusev
92
93
*
93
94
* @since 1.4
94
95
*/
@@ -286,6 +287,11 @@ public class AmqpAppender extends AppenderBase<ILoggingEvent> {
286
287
*/
287
288
private String charset ;
288
289
290
+ /**
291
+ * Whether or not add MDC properties into message headers. true by default for backward compatibility
292
+ */
293
+ private boolean addMdcAsHeaders = true ;
294
+
289
295
private boolean durable = true ;
290
296
291
297
private MessageDeliveryMode deliveryMode = MessageDeliveryMode .PERSISTENT ;
@@ -505,6 +511,14 @@ public void setMaxSenderRetries(int maxSenderRetries) {
505
511
this .maxSenderRetries = maxSenderRetries ;
506
512
}
507
513
514
+ public boolean isAddMdcAsHeaders () {
515
+ return this .addMdcAsHeaders ;
516
+ }
517
+
518
+ public void setAddMdcAsHeaders (boolean addMdcAsHeaders ) {
519
+ this .addMdcAsHeaders = addMdcAsHeaders ;
520
+ }
521
+
508
522
public boolean isDurable () {
509
523
return this .durable ;
510
524
}
@@ -750,6 +764,54 @@ else if ("headers".equals(this.exchangeType)) {
750
764
}
751
765
}
752
766
767
+ protected MessageProperties prepareMessageProperties (Event event ) {
768
+ ILoggingEvent logEvent = event .getEvent ();
769
+
770
+ String name = logEvent .getLoggerName ();
771
+ Level level = logEvent .getLevel ();
772
+
773
+ MessageProperties amqpProps = new MessageProperties ();
774
+ amqpProps .setDeliveryMode (this .deliveryMode );
775
+ amqpProps .setContentType (this .contentType );
776
+ if (null != this .contentEncoding ) {
777
+ amqpProps .setContentEncoding (this .contentEncoding );
778
+ }
779
+ amqpProps .setHeader (CATEGORY_NAME , name );
780
+ amqpProps .setHeader (THREAD_NAME , logEvent .getThreadName ());
781
+ amqpProps .setHeader (CATEGORY_LEVEL , level .toString ());
782
+ if (this .generateId ) {
783
+ amqpProps .setMessageId (UUID .randomUUID ().toString ());
784
+ }
785
+
786
+ // Set timestamp
787
+ Calendar tstamp = Calendar .getInstance ();
788
+ tstamp .setTimeInMillis (logEvent .getTimeStamp ());
789
+ amqpProps .setTimestamp (tstamp .getTime ());
790
+
791
+ // Copy properties in from MDC
792
+ if (this .addMdcAsHeaders ) {
793
+ Map <String , String > props = event .getProperties ();
794
+ Set <Entry <String , String >> entrySet = props .entrySet ();
795
+ for (Entry <String , String > entry : entrySet ) {
796
+ amqpProps .setHeader (entry .getKey (), entry .getValue ());
797
+ }
798
+ }
799
+
800
+ String [] location = this .locationLayout .doLayout (logEvent ).split ("\\ |" );
801
+ if (!"?" .equals (location [0 ])) {
802
+ amqpProps .setHeader (
803
+ "location" ,
804
+ String .format ("%s.%s()[%s]" , location [0 ], location [1 ], location [2 ]));
805
+ }
806
+
807
+ // Set applicationId, if we're using one
808
+ if (this .applicationId != null ) {
809
+ amqpProps .setAppId (this .applicationId );
810
+ }
811
+
812
+ return amqpProps ;
813
+ }
814
+
753
815
/**
754
816
* Subclasses may modify the final message before sending.
755
817
*
@@ -773,101 +835,78 @@ public void run() {
773
835
RabbitTemplate rabbitTemplate = new RabbitTemplate (AmqpAppender .this .connectionFactory );
774
836
while (true ) {
775
837
final Event event = AmqpAppender .this .events .take ();
776
- ILoggingEvent logEvent = event .getEvent ();
777
-
778
- String name = logEvent .getLoggerName ();
779
- Level level = logEvent .getLevel ();
780
-
781
- MessageProperties amqpProps = new MessageProperties ();
782
- amqpProps .setDeliveryMode (AmqpAppender .this .deliveryMode );
783
- amqpProps .setContentType (AmqpAppender .this .contentType );
784
- if (null != AmqpAppender .this .contentEncoding ) {
785
- amqpProps .setContentEncoding (AmqpAppender .this .contentEncoding );
786
- }
787
- amqpProps .setHeader (CATEGORY_NAME , name );
788
- amqpProps .setHeader (THREAD_NAME , logEvent .getThreadName ());
789
- amqpProps .setHeader (CATEGORY_LEVEL , level .toString ());
790
- if (AmqpAppender .this .generateId ) {
791
- amqpProps .setMessageId (UUID .randomUUID ().toString ());
792
- }
793
-
794
- // Set timestamp
795
- Calendar tstamp = Calendar .getInstance ();
796
- tstamp .setTimeInMillis (logEvent .getTimeStamp ());
797
- amqpProps .setTimestamp (tstamp .getTime ());
798
-
799
- // Copy properties in from MDC
800
- Map <String , String > props = event .getProperties ();
801
- Set <Entry <String , String >> entrySet = props .entrySet ();
802
- for (Entry <String , String > entry : entrySet ) {
803
- amqpProps .setHeader (entry .getKey (), entry .getValue ());
804
- }
805
- String [] location = AmqpAppender .this .locationLayout .doLayout (logEvent ).split ("\\ |" );
806
- if (!"?" .equals (location [0 ])) {
807
- amqpProps .setHeader (
808
- "location" ,
809
- String .format ("%s.%s()[%s]" , location [0 ], location [1 ], location [2 ]));
810
- }
811
- byte [] msgBody ;
812
- String routingKey = AmqpAppender .this .routingKeyLayout .doLayout (logEvent );
813
- // Set applicationId, if we're using one
814
- if (AmqpAppender .this .applicationId != null ) {
815
- amqpProps .setAppId (AmqpAppender .this .applicationId );
816
- }
817
-
818
- if (AmqpAppender .this .encoder != null && AmqpAppender .this .headerWritten .compareAndSet (false , true )) {
819
- byte [] header = AmqpAppender .this .encoder .headerBytes ();
820
- if (header != null && header .length > 0 ) {
821
- rabbitTemplate .convertAndSend (AmqpAppender .this .exchangeName , routingKey , header , m -> {
822
- if (AmqpAppender .this .applicationId != null ) {
823
- m .getMessageProperties ().setAppId (AmqpAppender .this .applicationId );
824
- }
825
- return m ;
826
- });
827
- }
828
- }
829
-
830
- if (AmqpAppender .this .abbreviator != null && logEvent instanceof LoggingEvent ) {
831
- ((LoggingEvent ) logEvent ).setLoggerName (AmqpAppender .this .abbreviator .abbreviate (name ));
832
- msgBody = encodeMessage (logEvent );
833
- ((LoggingEvent ) logEvent ).setLoggerName (name );
834
- }
835
- else {
836
- msgBody = encodeMessage (logEvent );
837
- }
838
-
839
- // Send a message
840
- try {
841
- Message message = new Message (msgBody , amqpProps );
842
-
843
- message = postProcessMessageBeforeSend (message , event );
844
- rabbitTemplate .send (AmqpAppender .this .exchangeName , routingKey , message );
845
- }
846
- catch (AmqpException e ) {
847
- int retries = event .incrementRetries ();
848
- if (retries < AmqpAppender .this .maxSenderRetries ) {
849
- // Schedule a retry based on the number of times I've tried to re-send this
850
- AmqpAppender .this .retryTimer .schedule (new TimerTask () {
851
-
852
- @ Override
853
- public void run () {
854
- AmqpAppender .this .events .add (event );
855
- }
856
-
857
- }, (long ) (Math .pow (retries , Math .log (retries )) * 1000 ));
858
- }
859
- else {
860
- addError ("Could not send log message " + logEvent .getMessage ()
861
- + " after " + AmqpAppender .this .maxSenderRetries + " retries" , e );
862
- }
863
- }
838
+
839
+ MessageProperties amqpProps = prepareMessageProperties (event );
840
+
841
+ String routingKey = AmqpAppender .this .routingKeyLayout .doLayout (event .getEvent ());
842
+
843
+ sendOneEncoderPatternMessage (rabbitTemplate , routingKey );
844
+
845
+ doSend (rabbitTemplate , event , event .getEvent (), name , amqpProps , routingKey );
864
846
}
865
847
}
866
848
catch (InterruptedException e ) {
867
849
Thread .currentThread ().interrupt ();
868
850
}
869
851
}
870
852
853
+ private void sendOneEncoderPatternMessage (RabbitTemplate rabbitTemplate , String routingKey ) {
854
+ /*
855
+ * If the encoder provides its pattern, send it as an additional one-time message.
856
+ */
857
+ if (AmqpAppender .this .encoder != null
858
+ && AmqpAppender .this .headerWritten .compareAndSet (false , true )) {
859
+ byte [] header = AmqpAppender .this .encoder .headerBytes ();
860
+ if (header != null && header .length > 0 ) {
861
+ rabbitTemplate .convertAndSend (AmqpAppender .this .exchangeName , routingKey , header , m -> {
862
+ if (AmqpAppender .this .applicationId != null ) {
863
+ m .getMessageProperties ().setAppId (AmqpAppender .this .applicationId );
864
+ }
865
+ return m ;
866
+ });
867
+ }
868
+ }
869
+ }
870
+
871
+ private void doSend (RabbitTemplate rabbitTemplate , final Event event , ILoggingEvent logEvent , String name ,
872
+ MessageProperties amqpProps , String routingKey ) {
873
+ byte [] msgBody ;
874
+ if (AmqpAppender .this .abbreviator != null && logEvent instanceof LoggingEvent ) {
875
+ ((LoggingEvent ) logEvent ).setLoggerName (AmqpAppender .this .abbreviator .abbreviate (name ));
876
+ msgBody = encodeMessage (logEvent );
877
+ ((LoggingEvent ) logEvent ).setLoggerName (name );
878
+ }
879
+ else {
880
+ msgBody = encodeMessage (logEvent );
881
+ }
882
+
883
+ // Send a message
884
+ try {
885
+ Message message = new Message (msgBody , amqpProps );
886
+
887
+ message = postProcessMessageBeforeSend (message , event );
888
+ rabbitTemplate .send (AmqpAppender .this .exchangeName , routingKey , message );
889
+ }
890
+ catch (AmqpException e ) {
891
+ int retries = event .incrementRetries ();
892
+ if (retries < AmqpAppender .this .maxSenderRetries ) {
893
+ // Schedule a retry based on the number of times I've tried to re-send this
894
+ AmqpAppender .this .retryTimer .schedule (new TimerTask () {
895
+
896
+ @ Override
897
+ public void run () {
898
+ AmqpAppender .this .events .add (event );
899
+ }
900
+
901
+ }, (long ) (Math .pow (retries , Math .log (retries )) * 1000 )); // NOSONAR magic #
902
+ }
903
+ else {
904
+ addError ("Could not send log message " + logEvent .getMessage ()
905
+ + " after " + AmqpAppender .this .maxSenderRetries + " retries" , e );
906
+ }
907
+ }
908
+ }
909
+
871
910
private byte [] encodeMessage (ILoggingEvent logEvent ) {
872
911
if (AmqpAppender .this .encoder != null ) {
873
912
return AmqpAppender .this .encoder .encode (logEvent );
0 commit comments