Package com.allen_sauer.gwt.log.client

Source Code of com.allen_sauer.gwt.log.client.RemoteLoggerImpl

/*
* Copyright 2010 Fred Sauer
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.allen_sauer.gwt.log.client;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.rpc.ServiceDefTarget;

import com.allen_sauer.gwt.log.shared.LogRecord;

import java.util.ArrayList;
import java.util.Iterator;

/**
* Logger which sends output via RPC to the server where it can be logged and aggregated.
*/
public final class RemoteLoggerImpl extends RemoteLogger {
  // CHECKSTYLE_JAVADOC_OFF

  private static final RemoteLoggerConfig config = GWT.create(RemoteLoggerConfig.class);
  private static final int MESSAGE_QUEUEING_DELAY_MILLIS_BASELINE = 300;
  private static final int MESSAGE_QUEUEING_DELAY_MILLIS_MAX_QUEUED = 5 * 60 * 1000; // 5 mins
  private static int messageQueueingDelayMillis = MESSAGE_QUEUEING_DELAY_MILLIS_BASELINE;
  private static final String REMOTE_LOGGER_NAME = "Remote Logger";
  private final AsyncCallback<ArrayList<LogRecord>> callback;
  private boolean callInProgressOrScheduled = false;
  private Throwable failure;
  private final ArrayList<LogRecord> logMessageList = new ArrayList<LogRecord>();
  private final ArrayList<LogRecord> queuedMessageList = new ArrayList<LogRecord>();
  private final RemoteLoggerServiceAsync service;

  private final Timer timer = new Timer() {
    @Override
    public void run() {
      movePendingMessagesToQueue();
      service.log(queuedMessageList, callback);
    }

    // No need to synchronize on collection since JavaScript is single-threaded
    private void movePendingMessagesToQueue() {
      queuedMessageList.addAll(logMessageList);
      logMessageList.clear();
    }
  };

  public RemoteLoggerImpl() {
    if (!GWT.isClient()) {
      throw new UnsupportedOperationException();
    }
    service = (RemoteLoggerServiceAsync) GWT.create(RemoteLoggerService.class);
    final ServiceDefTarget target = (ServiceDefTarget) service;
    String serviceEntryPointUrl = config.serviceEntryPointUrl();
    if (serviceEntryPointUrl != null) {
      target.setServiceEntryPoint(serviceEntryPointUrl);
    }

    callback = new AsyncCallback<ArrayList<LogRecord>>() {

      public void onFailure(Throwable ex) {
        String serviceEntryPoint = ((ServiceDefTarget) service).getServiceEntryPoint();
        if (messageQueueingDelayMillis > MESSAGE_QUEUEING_DELAY_MILLIS_MAX_QUEUED) {

          GWT.log(REMOTE_LOGGER_NAME
              + " has encountered too many failures while trying to contact servlet at "
              + serviceEntryPoint, ex);
          GWT.log(
              REMOTE_LOGGER_NAME + " has suspended with "
                  + (logMessageList.size() + queuedMessageList.size())
                  + " log message(s) not delivered", null);
          failure = ex;

          // log queued messages to other loggers before purging
          loggersLogToOthers(queuedMessageList);
          loggersLogToOthers(logMessageList);

          //purge
          logMessageList.clear();
          queuedMessageList.clear();
        } else {
          GWT.log(REMOTE_LOGGER_NAME
              + " encountered possibly transient communication failure with servlet at "
              + serviceEntryPoint, ex);
          GWT.log(REMOTE_LOGGER_NAME + " will attempt redelivery of " + queuedMessageList.size()
              + " log message(s) in " + messageQueueingDelayMillis + "ms", null);
        }
        callInProgressOrScheduled = false;
        maybeTriggerRPC();

        // exponential back-off
        messageQueueingDelayMillis += messageQueueingDelayMillis;
      }

      public void onSuccess(ArrayList<LogRecord> deobfuscatedLogRecords) {
        loggersLogToOthers(deobfuscatedLogRecords);
        queuedMessageList.clear();
        messageQueueingDelayMillis = MESSAGE_QUEUEING_DELAY_MILLIS_BASELINE;
        callInProgressOrScheduled = false;
        maybeTriggerRPC();
      }

      private void loggersLogToOthers(ArrayList<LogRecord> logRecords) {
        for (Iterator<LogRecord> iterator = logRecords.iterator(); iterator.hasNext();) {
          LogRecord record = iterator.next();
          RemoteLoggerImpl.super.loggersLog(record);
        }
      }
    };
  }

  @Override
  public void clear() {
  }

  @Override
  public boolean isSupported() {
    return true;
  }

  @Override
  public void log(LogRecord record) {
    if (failure != null) {
      // remote logger has been disabled; just pass on log messages to other loggers
      super.loggersLog(record);
      return;
    }
    if (record.getLevel() == Log.LOG_LEVEL_OFF) {
      // don't forward gwt-log diagnostic messages to the server; just pass on log messages to others
      super.loggersLog(record);
      return;
    }
    logMessageList.add(record);
    maybeTriggerRPC();
  }

  @Override
  public void loggersLog(LogRecord record) {
    log(record);
  }

  @Override
  public void setCurrentLogLevel(int level) {
  }

  private void maybeTriggerRPC() {
    if (failure == null && !callInProgressOrScheduled
        && (!logMessageList.isEmpty() || !queuedMessageList.isEmpty())) {
      callInProgressOrScheduled = true;
      timer.schedule(messageQueueingDelayMillis);
    }
  }
}
TOP

Related Classes of com.allen_sauer.gwt.log.client.RemoteLoggerImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.