44import static org .apache .commons .lang3 .ObjectUtils .firstNonNull ;
55
66import com .fasterxml .jackson .databind .JsonNode ;
7+ import com .fasterxml .jackson .databind .ObjectMapper ;
78import com .google .common .annotations .VisibleForTesting ;
89import com .google .common .base .Strings ;
910import com .google .common .base .Throwables ;
1011import com .google .common .collect .Maps ;
1112import com .wavefront .agent .api .APIContainer ;
12- import com .wavefront .agent .preprocessor .PreprocessorConfigManager ;
13+ import com .wavefront .agent .preprocessor .ProxyPreprocessorConfigManager ;
1314import com .wavefront .api .agent .AgentConfiguration ;
1415import com .wavefront .api .agent .ValidationConfiguration ;
1516import com .wavefront .common .Clock ;
3233import javax .ws .rs .ClientErrorException ;
3334import javax .ws .rs .ProcessingException ;
3435import org .apache .commons .lang .StringUtils ;
35- import org . apache .logging .log4j . LogManager ;
36- import org . apache .logging . log4j .Logger ;
36+ import java . util .logging .Level ;
37+ import java . util .logging .Logger ;
3738
3839/**
3940 * Registers the proxy with the back-end, sets up regular "check-ins" (every minute), transmits
4243 * @author vasily@wavefront.com
4344 */
4445public class ProxyCheckInScheduler {
45- private static final Logger logger = LogManager .getLogger ("proxy" );
46+ private static final Logger logger = Logger .getLogger ("proxy" );
4647 private static final int MAX_CHECKIN_ATTEMPTS = 5 ;
4748
4849 /**
@@ -68,7 +69,10 @@ public class ProxyCheckInScheduler {
6869 private volatile JsonNode agentMetrics ;
6970 private boolean retryImmediately = false ;
7071
72+ // check if preprocessor rules need to be sent to update BE
7173 public static AtomicBoolean preprocessorRulesNeedUpdate = new AtomicBoolean (false );
74+ // check if rules are set from FE/API
75+ public static AtomicBoolean isRulesSetInFE = new AtomicBoolean (false );
7276
7377 /**
7478 * @param proxyId Proxy UUID.
@@ -134,19 +138,60 @@ public void shutdown() {
134138 executor .shutdown ();
135139 }
136140
141+ /**
142+ * Initial sending of preprocessor rules. Will always check local location for preprocessor rule.
143+ */
144+ public void sendPreprocessorRules () {
145+ if (preprocessorRulesNeedUpdate .getAndSet (false )) {
146+ try {
147+ JsonNode rulesNode = createRulesNode (ProxyPreprocessorConfigManager .getProxyConfigRules (), null );
148+ apiContainer
149+ .getProxyV2APIForTenant (APIContainer .CENTRAL_TENANT_NAME )
150+ .proxySavePreprocessorRules (
151+ proxyId ,
152+ rulesNode
153+ );
154+ } catch (javax .ws .rs .NotFoundException ex ) {
155+ logger .warning ("'proxySavePreprocessorRules' api end point not found" );
156+ }
157+ }
158+ }
159+
137160 /** Send preprocessor rules */
138- private void sendPreprocessorRules () {
161+ private void sendPreprocessorRules (AgentConfiguration agentConfiguration ) {
139162 if (preprocessorRulesNeedUpdate .getAndSet (false )) {
163+ String preprocessorRules = null ;
164+ if (agentConfiguration .getPreprocessorRules () != null ) {
165+ // reading rules from BE if sent from BE
166+ preprocessorRules = agentConfiguration .getPreprocessorRules ();
167+ } else {
168+ // reading local file's rule
169+ preprocessorRules = ProxyPreprocessorConfigManager .getProxyConfigRules ();
170+ }
140171 try {
172+ JsonNode rulesNode = createRulesNode (preprocessorRules , agentConfiguration .getPreprocessorRulesId ());
141173 apiContainer
142- .getProxyV2APIForTenant (APIContainer .CENTRAL_TENANT_NAME )
143- .proxySavePreprocessorRules (proxyId , PreprocessorConfigManager .getJsonRules ());
174+ .getProxyV2APIForTenant (APIContainer .CENTRAL_TENANT_NAME )
175+ .proxySavePreprocessorRules (
176+ proxyId ,
177+ rulesNode
178+ );
144179 } catch (javax .ws .rs .NotFoundException ex ) {
145- logger .debug ("'proxySavePreprocessorRules' api end point not found" , ex );
180+ logger .warning ("'proxySavePreprocessorRules' api end point not found" );
146181 }
147182 }
148183 }
149184
185+ private JsonNode createRulesNode (String preprocessorRules , String proxyId ) {
186+ Map <String , String > fieldsMap = new HashMap <>();
187+ fieldsMap .put ("proxyRules" , preprocessorRules );
188+ if (proxyConfig .getPreprocessorConfigFile () != null ) fieldsMap .put ("proxyRulesFilePath" , proxyConfig .getPreprocessorConfigFile ());
189+ if (proxyId != null ) fieldsMap .put ("proxyRulesId" , proxyId );
190+
191+ ObjectMapper objectMapper = new ObjectMapper ();
192+ return objectMapper .valueToTree (fieldsMap );
193+ }
194+
150195 /**
151196 * Perform agent check-in and fetch configuration of the daemon from remote server.
152197 *
@@ -335,15 +380,15 @@ private Map<String, AgentConfiguration> checkin() {
335380 if (StringUtils .isBlank (logServerIngestionURL )
336381 || StringUtils .isBlank (logServerIngestionToken )) {
337382 proxyConfig .setReceivedLogServerDetails (false );
338- logger .error (
383+ logger .severe (
339384 WARNING_MSG
340385 + " To ingest logs to the log server, please provide "
341386 + "logServerIngestionToken & logServerIngestionURL in the proxy configuration." );
342387 }
343388 }
344389 } else if (StringUtils .isBlank (logServerIngestionURL )
345390 || StringUtils .isBlank (logServerIngestionToken )) {
346- logger .warn (
391+ logger .severe (
347392 WARNING_MSG
348393 + " Proxy will not be ingesting data to the log server as it did "
349394 + "not receive at least one of the values during check-in." );
@@ -358,7 +403,6 @@ private Map<String, AgentConfiguration> checkin() {
358403 void updateConfiguration () {
359404 try {
360405 Map <String , AgentConfiguration > configList = checkin ();
361- sendPreprocessorRules ();
362406 if (configList != null && !configList .isEmpty ()) {
363407 AgentConfiguration config ;
364408 for (Map .Entry <String , AgentConfiguration > configEntry : configList .entrySet ()) {
@@ -368,27 +412,53 @@ void updateConfiguration() {
368412 continue ;
369413 }
370414 if (configEntry .getKey ().equals (APIContainer .CENTRAL_TENANT_NAME )) {
371- if (logger .isDebugEnabled ( )) {
372- logger .debug ("Server configuration getShutOffAgents: " + config .getShutOffAgents ());
373- logger .debug ("Server configuration isTruncateQueue: " + config .isTruncateQueue ());
415+ if (logger .isLoggable ( Level . FINE )) {
416+ logger .fine ("Server configuration getShutOffAgents: " + config .getShutOffAgents ());
417+ logger .fine ("Server configuration isTruncateQueue: " + config .isTruncateQueue ());
374418 }
375419 if (config .getShutOffAgents ()) {
376- logger .warn (
420+ logger .severe (
377421 firstNonNull (
378422 config .getShutOffMessage (),
379423 "Shutting down: Server side flag indicating proxy has to shut down." ));
380424 shutdownHook .run ();
381425 } else if (config .isTruncateQueue ()) {
382- logger .warn (
426+ logger .severe (
383427 "Truncating queue: Server side flag indicating proxy queue has to be truncated." );
384428 truncateBacklog .run ();
385429 }
386430 }
387431 agentConfigurationConsumer .accept (configEntry .getKey (), config );
432+
433+ // Check if preprocessor rules were set on server side
434+ String checkPreprocessorRules = config .getPreprocessorRules ();
435+ if (checkPreprocessorRules != null && !checkPreprocessorRules .isEmpty ()) {
436+ AgentConfiguration finalConfig = config ;
437+ logger .log (Level .INFO , () -> String .format ("New preprocessor rules detected during checkin. Setting new preprocessor rule %s" ,
438+ (finalConfig .getPreprocessorRulesId () != null && !finalConfig .getPreprocessorRulesId ().isEmpty ()) ? finalConfig .getPreprocessorRulesId () : "" ));
439+ // future implementation, can send timestamp through AgentConfig and skip reloading if rule unchanged
440+ isRulesSetInFE .set (true );
441+ // indicates will need to sendPreprocessorRules()
442+ preprocessorRulesNeedUpdate .set (true );
443+ } else {
444+ // was previously reading from BE
445+ if (isRulesSetInFE .get ()) {
446+ if (proxyConfig .getPreprocessorConfigFile () == null || proxyConfig .getPreprocessorConfigFile ().isEmpty ()) {
447+ logger .info ("No preprocessor rules detected during checkin, and no rules file found." );
448+ } else {
449+ logger .log (Level .INFO , () -> String .format ("Reverting back to reading rules from file %s" , proxyConfig .getPreprocessorConfigFile ()));
450+ }
451+ // indicates that previously read from BE, now switching back to reading from file.
452+ isRulesSetInFE .set (false );
453+ preprocessorRulesNeedUpdate .set (true );
454+ }
455+ }
456+ // will always send to BE in order to update Agent with latest rule
457+ sendPreprocessorRules (config );
388458 }
389459 }
390460 } catch (Exception e ) {
391- logger .error ( "Exception occurred during configuration update" , e );
461+ logger .log ( Level . SEVERE , "Exception occurred during configuration update" , e );
392462 }
393463 }
394464
@@ -405,13 +475,13 @@ void updateProxyMetrics() {
405475 retries .set (0 );
406476 }
407477 } catch (Exception ex ) {
408- logger .error ( "Could not generate proxy metrics" , ex );
478+ logger .log ( Level . SEVERE , "Could not generate proxy metrics" , ex );
409479 }
410480 }
411481
412482 private void checkinError (String errMsg ) {
413- if (successfulCheckIns .get () == 0 ) logger .error (Strings .repeat ("*" , errMsg .length ()));
414- logger .error (errMsg );
415- if (successfulCheckIns .get () == 0 ) logger .error (Strings .repeat ("*" , errMsg .length ()));
483+ if (successfulCheckIns .get () == 0 ) logger .severe (Strings .repeat ("*" , errMsg .length ()));
484+ logger .severe (errMsg );
485+ if (successfulCheckIns .get () == 0 ) logger .severe (Strings .repeat ("*" , errMsg .length ()));
416486 }
417487}
0 commit comments