105105 *
106106 * - fingers_crossed:
107107 * - handler: the wrapped handler's name
108- * - [action_level|activation_strategy]: minimum level or service id to activate the handler, defaults to WARNING
108+ * - [action_level|activation_strategy]: minimum level or service id to activate the handler, defaults to null
109109 * - [excluded_404s]: if set, the strategy will be changed to one that excludes 404s coming from URLs matching any of those patterns
110110 * - [excluded_http_codes]: if set, the strategy will be changed to one that excludes specific HTTP codes (requires Symfony Monolog bridge 4.1+)
111111 * - [buffer_size]: defaults to 0 (unlimited)
328328 */
329329class Configuration implements ConfigurationInterface
330330{
331+ private $ acceptedParamsByHandlerType = [
332+ 'stream ' => ['path ' , 'level ' , 'bubble ' , 'file_permission ' , 'use_locking ' ],
333+ 'console ' => ['verbosity_levels ' , 'level ' , 'bubble ' , 'console_formater_options ' ],
334+ 'firephp ' => ['bubble ' , 'level ' ],
335+ 'browser_console ' => ['bubble ' , 'level ' ],
336+ 'gelf ' => ['publisher ' , 'bubble ' , 'level ' ],
337+ 'chromephp ' => ['bubble ' , 'level ' ],
338+ 'rotating_file ' => ['path ' , 'max_files ' , 'level ' , 'bubble ' , 'file_permission ' , 'filename_format ' , 'date_format ' ],
339+ 'mongo ' => ['mongo ' , 'level ' , 'bubble ' ],
340+ 'elasticsearch ' => ['elasticsearch ' , 'index ' , 'document_type ' , 'level ' , 'bubble ' ],
341+ 'redis ' => ['redis ' ],
342+ 'predis ' => ['redis ' ],
343+ 'fingers_crossed ' => [
344+ 'handler ' ,
345+ 'action_level ' ,
346+ 'activation_strategy ' ,
347+ 'excluded_404s ' ,
348+ 'excluded_http_codes ' ,
349+ 'buffer_size ' ,
350+ 'stop_buffering ' ,
351+ 'passthru_level ' ,
352+ 'bubble '
353+ ],
354+ 'filter ' => ['handler ' , 'accepted_levels ' , 'min_level ' , 'max_level ' , 'bubble ' ],
355+ 'buffer ' => ['handler ' , 'buffer_size ' , 'level ' , 'bubble ' , 'flush_on_overflow ' ],
356+ 'deduplication ' => ['handler ' , 'store ' , 'deduplication_level ' , 'time ' , 'bubble ' ],
357+ 'group ' => ['members ' , 'bubble ' ],
358+ 'whatfailuregroup ' => ['members ' , 'bubble ' ],
359+ 'syslog ' => ['ident ' , 'facility ' , 'logopts ' , 'level ' , 'bubble ' ],
360+ 'syslogudp ' => ['host ' , 'port ' , 'facility ' , 'logopts ' , 'level ' , 'bubble ' , 'ident ' ],
361+ 'swift_mailer ' => [
362+ 'from_email ' ,
363+ 'to_email ' ,
364+ 'subject ' ,
365+ 'email_prototype ' ,
366+ 'content_type ' ,
367+ 'mailer ' ,
368+ 'level ' ,
369+ 'bubble ' ,
370+ 'lazy '
371+ ],
372+ 'native_mailer ' => ['from_email ' , 'to_email ' , 'subject ' , 'level ' , 'bubble ' , 'headers ' ],
373+ 'socket ' => ['connection_string ' , 'timeout ' , 'connection_timeout ' , 'persistent ' , 'level ' , 'bubble ' ],
374+ 'pushover ' => ['token ' , 'user ' , 'title ' , 'level ' , 'bubble ' , 'timeout ' , 'connection_timeout ' ],
375+ 'raven ' => ['dsn ' , 'client_id ' , 'release ' , 'level ' , 'bubble ' , 'auto_log_stacks ' , 'environment ' ],
376+ 'sentry ' => ['dsn ' , 'client_id ' , 'release ' , 'level ' , 'bubble ' , 'auto_log_stacks ' , 'environment ' ],
377+ 'newrelic ' => ['level ' , 'bubble ' , 'app_name ' ],
378+ 'hipchat ' => [
379+ 'token ' ,
380+ 'room ' ,
381+ 'notify ' ,
382+ 'nickname ' ,
383+ 'level ' ,
384+ 'bubble ' ,
385+ 'use_ssl ' ,
386+ 'message_format ' ,
387+ 'host ' ,
388+ 'api_version ' ,
389+ 'timeout ' ,
390+ 'connection_timeout '
391+ ],
392+ 'slack ' => [
393+ 'token ' ,
394+ 'channel ' ,
395+ 'bot_name ' ,
396+ 'icon_emoji ' ,
397+ 'use_attachment ' ,
398+ 'use_short_attachment ' ,
399+ 'include_extra ' ,
400+ 'level ' ,
401+ 'bubble ' ,
402+ 'timeout ' ,
403+ 'connection_timeout '
404+ ],
405+ 'slackwebhook ' => [
406+ 'webhook_url ' ,
407+ 'channel ' ,
408+ 'bot_name ' ,
409+ 'icon_emoji ' ,
410+ 'use_attachment ' ,
411+ 'use_short_attachment ' ,
412+ 'include_extra ' ,
413+ 'level ' ,
414+ 'bubble '
415+ ],
416+ 'slackbot ' => ['team ' , 'token ' , 'channel ' , 'level ' , 'bubble ' ],
417+ 'cube ' => ['url ' , 'level ' , 'bubble ' ],
418+ 'amqp ' => ['exchange ' , 'exchange_name ' , 'level ' , 'bubble ' ],
419+ 'error_log ' => ['message_type ' , 'level ' , 'bubble ' ],
420+ 'null ' => ['level ' , 'bubble ' ],
421+ 'test ' => ['level ' , 'bubble ' ],
422+ 'debug ' => ['level ' , 'bubble ' ],
423+ 'loggly ' => ['token ' , 'level ' , 'bubble ' , 'tags ' ],
424+ 'logentries ' => ['token ' , 'use_ssl ' , 'level ' , 'bubble ' , 'timeout ' , 'connection_timeout ' ],
425+ 'insightops ' => ['token ' , 'region ' , 'use_ssl ' , 'level ' , 'bubble ' ],
426+ 'flowdock ' => ['token ' , 'source ' , 'from_email ' , 'level ' , 'bubble ' ],
427+ 'server_log ' => ['host ' , 'level ' , 'bubble ' ],
428+ ];
429+
331430 /**
332431 * Generates the configuration tree builder.
333432 *
@@ -774,6 +873,10 @@ public function getConfigTreeBuilder()
774873 ->scalarNode ('formatter ' )->end ()
775874 ->booleanNode ('nested ' )->defaultFalse ()->end ()
776875 ->end ()
876+ ->beforeNormalization ()
877+ ->always ()
878+ ->then (function ($ v ) { return $ this ->handlerTypeAcceptedOptionsValidation ($ v ); })
879+ ->end ()
777880 ->validate ()
778881 ->ifTrue (function ($ v ) { return 'service ' === $ v ['type ' ] && !empty ($ v ['formatter ' ]); })
779882 ->thenInvalid ('Service handlers can not have a formatter configured in the bundle, you must reconfigure the service itself instead ' )
@@ -794,10 +897,6 @@ public function getConfigTreeBuilder()
794897 ->ifTrue (function ($ v ) { return 'fingers_crossed ' === $ v ['type ' ] && !empty ($ v ['excluded_http_codes ' ]) && !empty ($ v ['excluded_404s ' ]); })
795898 ->thenInvalid ('You can not use excluded_http_codes together with excluded_404s in a FingersCrossedHandler ' )
796899 ->end ()
797- ->validate ()
798- ->ifTrue (function ($ v ) { return 'fingers_crossed ' !== $ v ['type ' ] && (!empty ($ v ['excluded_http_codes ' ]) || !empty ($ v ['excluded_404s ' ])); })
799- ->thenInvalid ('You can only use excluded_http_codes/excluded_404s with a FingersCrossedHandler definition ' )
800- ->end ()
801900 ->validate ()
802901 ->ifTrue (function ($ v ) { return 'filter ' === $ v ['type ' ] && "DEBUG " !== $ v ['min_level ' ] && !empty ($ v ['accepted_levels ' ]); })
803902 ->thenInvalid ('You can not use min_level together with accepted_levels in a FilterHandler ' )
@@ -963,4 +1062,119 @@ public function getConfigTreeBuilder()
9631062
9641063 return $ treeBuilder ;
9651064 }
1065+
1066+ private function handlerTypeAcceptedOptionsValidation (array $ v )
1067+ {
1068+ if (!array_key_exists ('type ' , $ v )) {
1069+ return $ v ;
1070+ }
1071+
1072+ if (!array_key_exists (strtolower ($ v ['type ' ]), $ this ->acceptedParamsByHandlerType )) {
1073+ return $ v ;
1074+ }
1075+
1076+ // @todo array_keys should be converted to lowercase?
1077+ $ acceptableParamsForHandlers = array_intersect ($ this ->provideAllConfigurationParams (), array_keys ($ v ));
1078+ $ unacceptableParamForHandler = array_diff (
1079+ $ acceptableParamsForHandlers ,
1080+ $ this ->acceptedParamsByHandlerType [strtolower ($ v ['type ' ])]
1081+ );
1082+ if (!empty ($ unacceptableParamForHandler )) {
1083+ throw new InvalidConfigurationException (sprintf (
1084+ 'The handler type %s does not support %s %s ' ,
1085+ strtolower ($ v ['type ' ]),
1086+ implode (', ' , $ unacceptableParamForHandler ),
1087+ count ($ unacceptableParamForHandler ) == 1 ? 'parameter ' : 'parameters '
1088+ ));
1089+ }
1090+
1091+ return $ v ;
1092+ }
1093+
1094+ private function provideAllConfigurationParams ()
1095+ {
1096+ return [
1097+ 'accepted_levels ' ,
1098+ 'action_level ' ,
1099+ 'activation_strategy ' ,
1100+ 'api_version ' ,
1101+ 'app_name ' ,
1102+ 'auto_log_stacks ' ,
1103+ 'bubble ' ,
1104+ 'bot_name ' ,
1105+ 'buffer_size ' ,
1106+ 'channel ' ,
1107+ 'client_id ' ,
1108+ 'config ' ,
1109+ 'connection_string ' ,
1110+ 'connection_timeout ' ,
1111+ 'console_formater_options ' ,
1112+ 'content_type ' ,
1113+ 'date_format ' ,
1114+ 'deduplication_level ' ,
1115+ 'document_type ' ,
1116+ 'dsn ' ,
1117+ 'elasticsearch ' ,
1118+ 'email_prototype ' ,
1119+ 'environment ' ,
1120+ 'exchange ' ,
1121+ 'exchange_name ' ,
1122+ 'excluded_404s ' ,
1123+ 'excluded_http_codes ' ,
1124+ 'facility ' ,
1125+ 'filename_format ' ,
1126+ 'file_permission ' ,
1127+ 'flush_on_overflow ' ,
1128+ 'from_email ' ,
1129+ 'handler ' ,
1130+ 'headers ' ,
1131+ 'host ' ,
1132+ 'icon_emoji ' ,
1133+ 'id ' ,
1134+ 'ident ' ,
1135+ 'include_extra ' ,
1136+ 'index ' ,
1137+ 'lazy ' ,
1138+ 'level ' ,
1139+ 'logopts ' ,
1140+ 'mailer ' ,
1141+ 'max_files ' ,
1142+ 'max_level ' ,
1143+ 'message_format ' ,
1144+ 'message_type ' ,
1145+ 'min_level ' ,
1146+ 'members ' ,
1147+ 'mongo ' ,
1148+ 'nickname ' ,
1149+ 'notify ' ,
1150+ 'path ' ,
1151+ 'passthru_level ' ,
1152+ 'persistent ' ,
1153+ 'port ' ,
1154+ 'publisher ' ,
1155+ 'redis ' ,
1156+ 'release ' ,
1157+ 'region ' ,
1158+ 'room ' ,
1159+ 'source ' ,
1160+ 'stop_buffering ' ,
1161+ 'store ' ,
1162+ 'subject ' ,
1163+ 'tags ' ,
1164+ 'team ' ,
1165+ 'time ' ,
1166+ 'timeout ' ,
1167+ 'title ' ,
1168+ 'token ' ,
1169+ 'to_email ' ,
1170+ 'url ' ,
1171+ 'user ' ,
1172+ 'use_attachment ' ,
1173+ 'use_locking ' ,
1174+ 'use_short_attachment ' ,
1175+ 'use_ssl ' ,
1176+ 'verbosity_levels ' ,
1177+ 'webhook_url ' ,
1178+ ];
1179+ }
9661180}
0 commit comments