Enabling Sleuth slows requests down (a lot) - netflix-feign

I use Spring Cloud Feign and Sleuth with a Zipkin server. My problem is that when I enable Sleuth, then any simple request takes at least 600ms. Note that for tests purposes, I've set the sampler percentage of Sleuth at 1.
Can I do something to improve that?
Here some log of a request which takes 25ms without Sleuth and 700ms with Sleuth. (user calls /teams which calls /cities):
13:46:46.064 [http-nio-8080-exec-3] DEBUG o.s.c.s.instrument.web.TraceFilter - Received a request to uri [/teams] that should not be sampled [false]
13:46:46.064 [http-nio-8080-exec-3] DEBUG o.s.c.s.instrument.web.TraceFilter - No parent span present - creating a new span
13:46:46.065 [http-nio-8080-exec-3] DEBUG o.s.web.servlet.DispatcherServlet - DispatcherServlet with name 'dispatcherServlet' processing GET request for [/teams]
13:46:46.078 [http-nio-8080-exec-3] DEBUG o.s.c.s.i.w.TraceHandlerInterceptor - Handling span [Trace: 99b8ae8aa88157a6, Span: 99b8ae8aa88157a6, Parent: null, exportable:true]
13:46:46.078 [http-nio-8080-exec-3] DEBUG o.s.c.s.i.w.TraceHandlerInterceptor - Adding a method tag with value [getTeams] to a span [Trace: 99b8ae8aa88157a6, Span: 99b8ae8aa88157a6, Parent: null, exportable:true]
13:46:46.078 [http-nio-8080-exec-3] DEBUG o.s.c.s.i.w.TraceHandlerInterceptor - Adding a class tag with value [TeamService] to a span [Trace: 99b8ae8aa88157a6, Span: 99b8ae8aa88157a6, Parent: null, exportable:true]
13:46:46.083 [hystrix-cities-2] DEBUG o.s.c.s.i.h.SleuthHystrixConcurrencyStrategy$HystrixTraceCallable - Continuing span [Trace: 99b8ae8aa88157a6, Span: 99b8ae8aa88157a6, Parent: null, exportable:true]
13:46:46.084 [hystrix-cities-2] DEBUG o.s.c.s.i.w.c.feign.TraceFeignClient - Created new Feign span [Trace: 99b8ae8aa88157a6, Span: 4cea0c5e2e662ea3, Parent: 99b8ae8aa88157a6, exportable:true]
13:46:46.084 [hystrix-cities-2] DEBUG o.s.c.s.i.w.c.feign.TraceFeignClient - The modified request equals GET http://localhost:8080/cities HTTP/1.1
X-B3-ParentSpanId: 99b8ae8aa88157a6
X-B3-Sampled: 1
X-B3-TraceId: 99b8ae8aa88157a6
X-Span-Name: http:/cities
X-B3-SpanId: 4cea0c5e2e662ea3
13:46:46.101 [http-nio-8080-exec-5] DEBUG o.s.c.s.instrument.web.TraceFilter - Received a request to uri [/cities] that should not be sampled [false]
13:46:46.101 [http-nio-8080-exec-5] DEBUG o.s.c.s.instrument.web.TraceFilter - Found a parent span [Trace: 99b8ae8aa88157a6, Span: 4cea0c5e2e662ea3, Parent: 99b8ae8aa88157a6, exportable:true] in the request
13:46:46.101 [http-nio-8080-exec-5] DEBUG o.s.c.s.instrument.web.TraceFilter - Parent span is [Trace: 99b8ae8aa88157a6, Span: 4cea0c5e2e662ea3, Parent: 99b8ae8aa88157a6, exportable:true]
13:46:46.101 [http-nio-8080-exec-5] DEBUG o.s.b.w.f.OrderedRequestContextFilter - Bound request context to thread: org.apache.catalina.connector.RequestFacade#36324069
13:46:46.101 [http-nio-8080-exec-5] DEBUG o.s.web.servlet.DispatcherServlet - DispatcherServlet with name 'dispatcherServlet' processing GET request for [/cities]
13:46:46.105 [http-nio-8080-exec-5] DEBUG o.s.c.s.i.w.TraceHandlerInterceptor - Handling span [Trace: 99b8ae8aa88157a6, Span: 4cea0c5e2e662ea3, Parent: 99b8ae8aa88157a6, exportable:true]
13:46:46.105 [http-nio-8080-exec-5] DEBUG o.s.c.s.i.w.TraceHandlerInterceptor - Adding a method tag with value [getCities] to a span [Trace: 99b8ae8aa88157a6, Span: 4cea0c5e2e662ea3, Parent: 99b8ae8aa88157a6, exportable:true]
13:46:46.105 [http-nio-8080-exec-5] DEBUG o.s.c.s.i.w.TraceHandlerInterceptor - Adding a class tag with value [cityService] to a span [Trace: 99b8ae8aa88157a6, Span: 4cea0c5e2e662ea3, Parent: 99b8ae8aa88157a6, exportable:true]
13:46:46.106 [http-nio-8080-exec-5] DEBUG o.s.w.s.m.m.a.RequestResponseBodyMethodProcessor - Written [com.citymanager.entity.City#320dc277] as "application/json" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter#33bb3f86]
13:46:46.107 [http-nio-8080-exec-5] DEBUG o.s.c.s.instrument.web.TraceFilter - Trying to send the parent span [Trace: 99b8ae8aa88157a6, Span: 4cea0c5e2e662ea3, Parent: 99b8ae8aa88157a6, exportable:true] to Zipkin
13:46:46.107 [http-nio-8080-exec-5] DEBUG o.s.c.s.z.ServerPropertiesEndpointLocator - Span will contain serviceName [city-manager]
13:46:46.109 [hystrix-cities-2] DEBUG o.s.c.s.i.w.c.feign.TraceFeignClient - Closing Feign span and logging CR [Trace: 99b8ae8aa88157a6, Span: 4cea0c5e2e662ea3, Parent: 99b8ae8aa88157a6, exportable:true]
13:46:46.109 [hystrix-cities-2] DEBUG o.s.c.s.i.w.c.feign.TraceFeignClient - Closing Feign span [Trace: 99b8ae8aa88157a6, Span: 4cea0c5e2e662ea3, Parent: 99b8ae8aa88157a6, exportable:true]
13:46:46.109 [hystrix-cities-2] DEBUG o.s.c.s.z.ServerPropertiesEndpointLocator - Span will contain serviceName [city-manager]
13:46:46.459 [http-nio-8080-exec-5] DEBUG o.s.c.s.instrument.web.TraceFilter - Closing the span [Trace: 99b8ae8aa88157a6, Span: 4cea0c5e2e662ea3, Parent: 99b8ae8aa88157a6, exportable:true] since the response was successful
13:46:46.464 [hystrix-cities-2] DEBUG o.s.w.c.HttpMessageConverterExtractor - Reading [class com.citymanager.entity.City] as "application/json;charset=UTF-8" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter#33bb3f86]
13:46:46.465 [hystrix-cities-2] DEBUG o.s.c.s.i.h.SleuthHystrixConcurrencyStrategy$HystrixTraceCallable - Detaching span since it was continued [Trace: 99b8ae8aa88157a6, Span: 99b8ae8aa88157a6, Parent: null, exportable:true]
13:46:46.466 [http-nio-8080-exec-3] DEBUG o.s.w.s.m.m.a.RequestResponseBodyMethodProcessor - Written [com.citymanager.entity.Team#3c35ed9b] as "application/json" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter#33bb3f86]
13:46:46.466 [http-nio-8080-exec-3] DEBUG o.s.web.servlet.DispatcherServlet - Successfully completed request
13:46:46.467 [http-nio-8080-exec-3] DEBUG o.s.c.s.instrument.web.TraceFilter - Closing the span [Trace: 99b8ae8aa88157a6, Span: 99b8ae8aa88157a6, Parent: null, exportable:true] since the response was successful
13:46:46.467 [http-nio-8080-exec-3] DEBUG o.s.c.s.z.ServerPropertiesEndpointLocator - Span will contain serviceName [city-manager]
13:46:46.857 [AsyncReporter(org.springframework.cloud.sleuth.zipkin.RestTemplateSender#42519b72)] DEBUG o.s.web.client.RestTemplate - Created POST request for "http://localhost:9411/api/v1/spans"
13:46:46.857 [AsyncReporter(org.springframework.cloud.sleuth.zipkin.RestTemplateSender#42519b72)] DEBUG o.s.web.client.RestTemplate - Setting request Accept header to [text/plain, application/json, application/*+json, */*]
13:46:46.857 [AsyncReporter(org.springframework.cloud.sleuth.zipkin.RestTemplateSender#42519b72)] DEBUG o.s.web.client.RestTemplate - Writing [[B#1aecb2f4] as "application/json" using [org.springframework.http.converter.ByteArrayHttpMessageConverter#4414cc2d]
13:46:46.885 [AsyncReporter(org.springframework.cloud.sleuth.zipkin.RestTemplateSender#42519b72)] DEBUG o.s.web.client.RestTemplate - POST request for "http://localhost:9411/api/v1/spans" resulted in 202 (null)

I belive you had problem with: org.springframework.cloud.sleuth.zipkin.ServerPropertiesEndpointLocator.
It uses InetUtils.findFirstNonLoopbackAddress() to determine instance address. Method is called synchronously when each span is close (in ZipkinSpanListener#convert). The workaround is to create custom org.springframework.cloud.sleuth.zipkin.EndpointLocator. You can use something like that:
class CachingEndpointLocator implements EndpointLocator {
private final Endpoint endpoint;
CachingEndpointLocator(EndpointLocator delegate) {
this.endpoint = delegate.local();
}
#Override
public Endpoint local() {
return endpoint;
}
}
And combine it with one of existing EndpointLocators. You can find them in: org.springframework.cloud.sleuth.zipkin.ZipkinAutoConfiguration.
This issue is already fixed in sleuth 2.X.X. Where: org.springframework.cloud.sleuth.zipkin2.DefaultEndpointLocator caches server address:
public DefaultEndpointLocator(Registration registration,
ServerProperties serverProperties, Environment environment,
ZipkinProperties zipkinProperties, InetUtils inetUtils) {
this.registration = registration;
this.serverProperties = serverProperties;
this.environment = environment;
this.zipkinProperties = zipkinProperties;
this.firstNonLoopbackAddress = findFirstNonLoopbackAddress(inetUtils);
}

It seems like you are using Sleuth with Zipkin via HTTP. You can try the Sleuth with Zipkin via Spring Cloud Stream approach. I haven't done the benchmark myself, but it should improve the performance in theory.
Please see the documentation at: https://cloud.spring.io/spring-cloud-sleuth/spring-cloud-sleuth.html#_sleuth_with_zipkin_via_spring_cloud_stream

I wonder what kind of a benchmarking method you have picked. Which version of Sleuth are you using? Also is this one single benchmark that you're doing? Is it on your computer? Has the JVM gotten heated up? Are there any other processes executed? Doing benchmarking is not that easy... You can use tools like JMH to do it better.
BTW try turning off the DEBUG logging level and check the results again.
We are performing benchmark tests of Sleuth and from what we see when adding Sleuth the latency gets increased by around 20 ms. Definitely not 600 ms.

Related

Get " Class is not registered:" exception during Gremlin Query

I'm using Gremlin to connect with Janusgraph. Right now, I'd like to program a gremlin query statement to get specific Vertex by label with ignoring case-sensitive. So, my query like this:
g.V(vertexId).inE(edgeLabel).outV().filter(it -> it.get().label().equalsIgnoreCase(label)) ;
However, the execution caused a exception:
java.lang.IllegalArgumentException: Class is not registered: com.demo.service.kg.KGService$$Lambda$506/1884099229
Note: To register this class use: kryo.register(com.demo.service.kg.KGService$$Lambda$506/1884099229.class);
My configuration is:
hosts: [localhost]
port: 8182
connectionPool: { maxContentLength: 7000000 }
serializer: { className: org.apache.tinkerpop.gremlin.driver.ser.GryoMessageSerializerV3d0,
config: { ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistry],
serializeResultToString: true}}
Is there anyone knows what is going on?
Lambdas will not serialize that way. You have to submit them as strings
g.V(vertexId).inE(edgeLabel).outV().filter(
Lambda.predicate("it -> it.get().label().equalsIgnoreCase(label)")) ;

Spring boot 404 and still works

When i run my spring boot application as JAR file, all my controllers work fine(though i still get "Did not find handler method for ..." in logs but somehow appropriate controller and view is rendered just fine. When i run this in WAR mode, it's giving me 404 with same error in logs "Did not find handler method for ...".
Here is my application class:
#SpringBootApplication
public class RAApplication extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
//set register error pagefilter false
//setRegisterErrorPageFilter(false);
return application.sources(RAApplication.class);
}
public static void main(String[] args) throws Exception {
SpringApplication.run(RAApplication.class, args);
}
}
My main application class is under com.xyz.abc and all controllers under say com.xyz.abc.controllers and every other component is in child package of com.xyz.abc .
/mappings and /beans work just fine and /mappings do show something like this :
"{[/],methods=[GET]}":{"bean":"requestMappingHandlerMapping","method":"public java.lang.String com.xyz.abc.controllers.HomeController.renderIndexPage(org.springframework.ui.Model)"}
FYI, I checked there is only one mapping of [/] in case it's useful.
Any pointers to what might be going wrong? All usual searches points to controllers not being found but /mappings show all of them are mapped correctly but why does it give 404 in war mode and works with error in jar mode?
Thanks!
UPDATE : I've set
servlet.contextPath=/
in application.properties and rest other actuator endpoints are configured correctly too e.g.
15:21:09.253 [localhost-startStop-1] INFO org.springframework.boot.web.servlet.FilterRegistrationBean - Mapping filter: 'metricsFilter' to: [/*]
15:21:09.254 [localhost-startStop-1] INFO org.springframework.boot.web.servlet.FilterRegistrationBean - Mapping filter: 'characterEncodingFilter' to: [/*]
15:21:09.254 [localhost-startStop-1] INFO org.springframework.boot.web.servlet.FilterRegistrationBean - Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
15:21:09.254 [localhost-startStop-1] INFO org.springframework.boot.web.servlet.FilterRegistrationBean - Mapping filter: 'httpPutFormContentFilter' to: [/*]
15:21:09.254 [localhost-startStop-1] INFO org.springframework.boot.web.servlet.FilterRegistrationBean - Mapping filter: 'requestContextFilter' to: [/*]
15:21:09.255 [localhost-startStop-1] INFO org.springframework.boot.web.servlet.FilterRegistrationBean - Mapping filter: 'webRequestLoggingFilter' to: [/*]
15:21:09.255 [localhost-startStop-1] INFO org.springframework.boot.web.servlet.FilterRegistrationBean - Filter errorPageFilter was not registered (disabled)
15:21:09.255 [localhost-startStop-1] INFO org.springframework.boot.web.servlet.FilterRegistrationBean - Mapping filter: 'applicationContextIdFilter' to: [/*]
15:21:09.255 [localhost-startStop-1] INFO org.springframework.boot.web.servlet.ServletRegistrationBean - Mapping servlet: 'dispatcherServlet' to [/]
15:21:09.289 [localhost-startStop-1] DEBUG org.springframework.boot.web.filter.OrderedRequestContextFilter - Initializing filter 'requestContextFilter'
15:21:09.291 [localhost-startStop-1] DEBUG org.springframework.boot.web.filter.OrderedRequestContextFilter - Filter 'requestContextFilter' configured successfully
15:21:09.291 [localhost-startStop-1] DEBUG org.springframework.boot.web.filter.ApplicationContextHeaderFilter - Initializing filter 'applicationContextIdFilter'
15:21:09.291 [localhost-startStop-1] DEBUG org.springframework.boot.web.filter.ApplicationContextHeaderFilter - Filter 'applicationContextIdFilter' configured successfully
If you deploy your WAR in a web container like Tomcat then you have a context path.
For example localhost:8080/ in JAR mode becomes localhost:8080/myapp/ in web container.

Symfony service's tags exception (YAML)

This gives exception (Tags must be array, check YAML syntax):
services:
application.presentation.twig.extension.nullableDateTime:
class: AppBundle\Application\Presentation\Twig\Extension\NullableDateTime
tags: [twig.extension]
This does not:
services:
application.presentation.twig.extension.nullableDateTime:
class: AppBundle\Application\Presentation\Twig\Extension\NullableDateTime
tags:
- {name: twig.extension}
Why is that? The Symfony docs says to use [] for tags.
I have used the {} syntax somewhere else, maybe only one syntax is accepted?
https://symfony.com/doc/current/service_container/tags.html

Spring Profile values getting mixed

I'm using Spring Boot 1.4.3.RELEASE and gradle 2.13 for developing an api. On local environment, 'local' profile is working perfectly, but I'm getting issue while deploying code in Linux/Unix server.
Here is my application.yml with two profiles : dev and local
---
spring:
profiles:
active: dev
server:
context-path: /api/v1
port: 8080
build:
version: 1.0.0
cache:
storage:
path: '/home/user/content/storage/'
---
spring:
profiles:
active: local
server:
context-path: /content-delivery/api/v1
port: 8081
build:
version: 1.0.0
cache:
storage:
path: '/Yogen/api/code/cachedData'
The command I'm using to deploy my war file is:
jdk1.8.0_112/bin/java -jar _-Dspring.profiles.active=dev content-delivery.jar
When I run my war it was working fine with only one profile, but once i added another profile, I'm getting values get mixed up causing error as below:
01:56:16.557 INFO ContentDeliveryApplication - The following profiles are active: dev
............
02:00:48.182 INFO PropertyPlaceholderConfigurer - Loading properties file from file [/home/542596/content-api/resources/app-dev.properties]
02:00:51.939 INFO PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'org.springframework.ws.config.annotation.DelegatingWsConfiguration' of type [class org.springframework.ws.config.annotation.DelegatingWsConfiguration$$EnhancerBySpringCGLIB$$290c5e2d] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
02:00:55.736 INFO AnnotationActionEndpointMapping - Supporting [WS-Addressing August 2004, WS-Addressing 1.0]
02:01:25.559 INFO PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration' of type [class org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration$$EnhancerBySpringCGLIB$$a08e9c2b] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
02:01:56.522 INFO TomcatEmbeddedServletContainer - Tomcat initialized with port(s): 8081 (http)
02:01:57.669 INFO StandardService - Starting service Tomcat
02:01:57.877 INFO StandardEngine - Starting Servlet Engine: Apache Tomcat/8.5.6
02:02:11.228 INFO [/content-delivery/api/v1] - Initializing Spring embedded WebApplicationContext
02:02:11.228 INFO ContextLoader - Root WebApplicationContext: initialization completed in 353263 ms
02:02:19.412 INFO ServletRegistrationBean - Mapping servlet: 'dispatcherServlet' to [/]
02:02:19.517 INFO ServletRegistrationBean - Mapping servlet: 'messageDispatcherServlet' to [/services/*]
02:02:19.829 INFO FilterRegistrationBean - Mapping filter: 'metricsFilter' to: [/*]
02:02:19.829 INFO FilterRegistrationBean - Mapping filter: 'characterEncodingFilter' to: [/*]
02:02:19.829 INFO FilterRegistrationBean - Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
02:02:19.829 INFO FilterRegistrationBean - Mapping filter: 'httpPutFormContentFilter' to: [/*]
02:02:19.829 INFO FilterRegistrationBean - Mapping filter: 'requestContextFilter' to: [/*]
02:02:19.829 INFO FilterRegistrationBean - Mapping filter: 'webRequestLoggingFilter' to: [/*]
02:02:19.829 INFO FilterRegistrationBean - Mapping filter: 'applicationContextIdFilter' to: [/*]
02:02:46.283 ERROR EhcacheManager - Initialize failed.
02:02:46.284 WARN AnnotationConfigEmbeddedWebApplicationContext - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jsonObjectCacheManager': Invocation of init method failed; nested exception is org.ehcache.StateTransitionException: Directory couldn't be created: /Yogen/api/code/cachedData/cachedData
02:02:46.285 INFO StandardService - Stopping service Tomcat
02:02:47.528 INFO AutoConfigurationReportLoggingInitializer -
Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled.
02:02:48.103 ERROR SpringApplication - Application startup failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jsonObjectCacheManager': Invocation of init method failed; nested exception is org.ehcache.StateTransitionException: Directory couldn't be created: /Yogen/api/code/cachedData/cachedData
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:137) ~[spring-beans-4.3.5.RELEASE.jar!/:4.3.5.RELEASE]
The PropertyPlaceholderConfigurer has been configured as follows:
#Configuration
public class PropertyConfiguration {
#Bean
#Profile("dev")
public static PropertyPlaceholderConfigurer developmentPropertyPlaceholderConfigurer() {
PropertyPlaceholderConfigurer configurer = new PropertyPlaceholderConfigurer();
configurer.setLocation(new FileSystemResource("/home/542596/content-api/resources/app-dev.properties"));
configurer.setIgnoreUnresolvablePlaceholders(true);
return configurer;
}
}
The console shows that properties file being read is correct also the profile is 'dev', but the port started and context-path and other values are being fetched from 'local' profile instead 'dev' profile.
What I'm missing?? Thanks.
Your profiles are getting overridden.
Better Boostrap your application using bootstrap.yml
and have two application.yml as follows :
application-dev.yml
application-local.yml
set profiles in bootstrap.yml to decide which property file to load:
spring:
profiles:
active : dev # choose which application properties to load dev/local
Like #Barath stated, you cannot separate profile properties within a single application.yml file. Create a yml file for each profile, name it as follows
application-{profile}.yml
I would not use bootstrap.yml to specify which profile to load as you'll want to externalize this if possible, so passing it to the VM via -Dspring.profiles.active=dev would be preferable.
We also have another option similar to #Maxwell answer instead of passing the profile through VM property :
you can have following files:
application.yml
application-dev.yml
application-local.yml
And define profile in application.yml :
spring:
profiles:
active : dev
This ensures loading of application.yml as well as application-dev.yml.

Monolog: log different channels and multiple handlers to grouped log file + dedicated log files

I'm facing some problems with configuring Monolog to handle "nested loggers".
What I want to do:
Log from services to dedicated files (one per service) AND from all services to one file. Each logger should be also handled by monolog.handlers.console.
Why I want to do
Each service has logic, but can use other services from DI. I want to know what exactly one service logs, so I want dedicated logger (with custom channel and custom log file) for each service. But when services relies on other services, I want to read logs in chronological order in one file.
What I have
app/config.yml:
monolog:
handlers:
my_handler:
type: stream
path: %kernel.logs_dir%/%kernel.environment%.my.log
level: info
handler: my_bundle_handler
src/My/Bundle/Resources/config/config.yml
services:
# LOGGERS
my_logger:
class: Symfony\Bridge\Monolog\Logger
arguments: [my_logger]
calls:
- [pushHandler, [#monolog.handler.console]]
- [pushHandler, [#my_bundle_handler]]
tags:
- { name: monolog.logger, channel: my_channel}
# HANDLERS
my_bundle_handler:
abstract: true # Without it it will throw exception
type: group
members: [my_service_handler]
channels: ["my_channel"]
tags:
- { name: log_handler }
my_service_handler:
class: Monolog\Handler\StreamHandler
arguments: [%kernel.logs_dir%/%kernel.environment%.my_service.log, 100]
channels: ["my_channel"]
tags:
- { name: log_handler }
It does not work as expected. It logs to my_service.log, but not to my.log.
Is there possibility to achieve what I want?
Channels in monolog works exactly like you want. Sample monolog configuration
app/config.yml
monolog:
channels: ['deletion']
handlers:
main:
type: fingers_crossed
action_level: error
handler: grouped_main
formatter: "monolog.formatter.request"
buffer_size: 30
# if you will set stop_buffering: true - you will get ALL events after first error. It could produce huge logs for console
stop_buffering: false
# this is for getsentry.com error catching
sentry:
type: raven
dsn: '%sentry_url%'
level: notice
# Groups
grouped_main:
type: group
members: [sentry, streamed_main, streamed_main_brief]
# Streams
streamed_main:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
streamed_main_brief:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%_brief.log"
formatter: monolog.brief_formatter
console:
type: console
formatter: monolog.console_formatter
deletion:
# log deletion related messages
level: debug
type: stream
path: '%kernel.logs_dir%/deletion.log'
channels: ['deletion']
formatter: monolog.brief_formatter
services:
my_service:
class: Monolog\Processor\IntrospectionProcessor
tags:
- { name: monolog.processor }
monolog.console_formatter:
class: Symfony\Bridge\Monolog\Formatter\ConsoleFormatter
arguments:
- "<fg=black;bg=green>[%%datetime%%]</fg=black;bg=green> %%start_tag%%%%message%%%%end_tag%%\n"
monolog.brief_formatter:
class: Monolog\Formatter\LineFormatter
arguments:
- "[%%datetime%%] %%message%%\n"
# default format is
# - "[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n"
If you will add code like
$this->getContainer()->get("logger")->info("Sample info");
$this->getContainer()->get("monolog.logger.deletion")->info("Deletion channel info");
$this->getContainer()->get("monolog.logger.deletion")->error("Deletion channel error");
$this->getContainer()->get("monolog.logger.deletion")->info("Deletion channel info #2");
You will get 3 log files with such a content
Channel log file
deletion.log
[2016-11-11 12:43:18] Deletion channel info
[2016-11-11 12:43:18] Deletion channel error
[2016-11-11 12:43:19] Deletion channel info #2
Default env log file
dev.log
[2016-11-11 12:43:18] event.DEBUG: Notified event "console.command" to listener "Symfony\Component\HttpKernel\EventListener\DebugHandlersListener::configure". [] {"file":"...."}
[2016-11-11 12:43:18] event.DEBUG: Notified event "console.command" to listener "Symfony\Bridge\Monolog\Handler\ConsoleHandler::onCommand". [] {"file":"...."}
[2016-11-11 12:43:18] app.INFO: Sample info [] {"file":"..."}
[2016-11-11 12:43:18] deletion.INFO: Deletion channel info [] {"file":"...."}
[2016-11-11 12:43:18] deletion.ERROR: Deletion channel error [] {"...."}
Brief env.log
[2016-11-11 12:43:18] Notified event "console.command" to listener "Symfony\Component\HttpKernel\EventListener\DebugHandlersListener::configure".
[2016-11-11 12:43:18] Notified event "console.command" to listener "Symfony\Bridge\Monolog\Handler\ConsoleHandler::onCommand".
[2016-11-11 12:43:18] Sample info
[2016-11-11 12:43:18] Deletion channel info
[2016-11-11 12:43:18] Deletion channel error
Also notice, that because of stop_buffering: false notice after error will not appear at dev.log, dev_brief.log, but will appear at deletion.log
And you should try sentry - its great product and his owners are cool guys :)

Resources