use of com.microsoft.appcenter.ingestion.models.Log in project mobile-center-sdk-android by Microsoft.
the class DefaultChannel method handleSendingSuccess.
/**
* The actual implementation to react to sending a batch to the server successfully.
*
* @param groupState The group state.
* @param currentState The current state.
* @param batchId The batch ID.
*/
private synchronized void handleSendingSuccess(@NonNull final GroupState groupState, int currentState, @NonNull final String batchId) {
if (checkStateDidNotChange(groupState, currentState)) {
String groupName = groupState.mName;
mPersistence.deleteLogs(groupName, batchId);
List<Log> removedLogsForBatchId = groupState.mSendingBatches.remove(batchId);
GroupListener groupListener = groupState.mListener;
if (groupListener != null) {
for (Log log : removedLogsForBatchId) {
groupListener.onSuccess(log);
}
}
checkPendingLogs(groupName);
}
}
use of com.microsoft.appcenter.ingestion.models.Log in project mobile-center-sdk-android by Microsoft.
the class DefaultChannel method suspend.
/**
* Stop sending logs until app is restarted or the channel is enabled again.
*
* @param deleteLogs in addition to suspending, if this is true, delete all logs from Persistence.
* @param exception the exception that caused suspension.
*/
private void suspend(boolean deleteLogs, Exception exception) {
mEnabled = false;
mDiscardLogs = deleteLogs;
mCurrentState++;
for (GroupState groupState : mGroupStates.values()) {
cancelTimer(groupState);
/* Delete all other batches and call callback method that are currently in progress. */
for (Iterator<Map.Entry<String, List<Log>>> iterator = groupState.mSendingBatches.entrySet().iterator(); iterator.hasNext(); ) {
Map.Entry<String, List<Log>> entry = iterator.next();
List<Log> removedLogsForBatchId = groupState.mSendingBatches.get(entry.getKey());
iterator.remove();
if (deleteLogs) {
GroupListener groupListener = groupState.mListener;
if (groupListener != null) {
for (Log log : removedLogsForBatchId) {
groupListener.onFailure(log, exception);
}
}
}
}
}
try {
mIngestion.close();
} catch (IOException e) {
AppCenterLog.error(LOG_TAG, "Failed to close ingestion", e);
}
if (deleteLogs) {
for (GroupState groupState : mGroupStates.values()) {
deleteLogsOnSuspended(groupState);
}
} else {
mPersistence.clearPendingLogState();
}
}
use of com.microsoft.appcenter.ingestion.models.Log in project mobile-center-sdk-android by Microsoft.
the class DefaultChannel method deleteLogsOnSuspended.
private void deleteLogsOnSuspended(final GroupState groupState) {
final List<Log> logs = new ArrayList<>();
mPersistence.getLogs(groupState.mName, CLEAR_BATCH_SIZE, logs);
if (logs.size() > 0 && groupState.mListener != null) {
for (Log log : logs) {
groupState.mListener.onBeforeSending(log);
groupState.mListener.onFailure(log, new CancellationException());
}
}
if (logs.size() >= CLEAR_BATCH_SIZE && groupState.mListener != null) {
deleteLogsOnSuspended(groupState);
} else {
mPersistence.deleteLogs(groupState.mName);
}
}
use of com.microsoft.appcenter.ingestion.models.Log in project mobile-center-sdk-android by Microsoft.
the class DefaultChannel method triggerIngestion.
/**
* This will, if we're not using the limit for pending batches, trigger sending of a new request.
* It will also reset the counters for sending out items for both the number of items enqueued and
* the handlers. It will do this even if we don't have reached the limit
* of pending batches or the time interval.
*
* @param groupName the group name
*/
private synchronized void triggerIngestion(@NonNull final String groupName) {
if (!mEnabled) {
return;
}
final GroupState groupState = mGroupStates.get(groupName);
int pendingLogCount = groupState.mPendingLogCount;
int maxFetch = Math.min(pendingLogCount, groupState.mMaxLogsPerBatch);
AppCenterLog.debug(LOG_TAG, "triggerIngestion(" + groupName + ") pendingLogCount=" + pendingLogCount);
cancelTimer(groupState);
/* Check if we have reached the maximum number of pending batches, log to LogCat and don't trigger another sending. */
if (groupState.mSendingBatches.size() == groupState.mMaxParallelBatches) {
AppCenterLog.debug(LOG_TAG, "Already sending " + groupState.mMaxParallelBatches + " batches of analytics data to the server.");
return;
}
/* Get a batch from Persistence. */
final List<Log> batch = new ArrayList<>(maxFetch);
final int stateSnapshot = mCurrentState;
final String batchId = mPersistence.getLogs(groupName, maxFetch, batch);
/* Decrement counter. */
groupState.mPendingLogCount -= maxFetch;
/* Nothing more to do if no logs. */
if (batchId == null) {
return;
}
AppCenterLog.debug(LOG_TAG, "ingestLogs(" + groupState.mName + "," + batchId + ") pendingLogCount=" + groupState.mPendingLogCount);
/* Call group listener before sending logs to ingestion service. */
if (groupState.mListener != null) {
for (Log log : batch) {
groupState.mListener.onBeforeSending(log);
}
}
/* Remember this batch. */
groupState.mSendingBatches.put(batchId, batch);
/*
* Due to bug on old Android versions (verified on 4.0.4),
* if we start an async task from here, i.e. the async persistence handler thread,
* we end up with AsyncTask configured with the wrong Handler to use for onPostExecute
* instead of using main thread as advertised in Javadoc (and its a static field there).
*
* Our SDK guards against an application that would make a first async task in non UI
* thread before SDK is initialized, but we should also avoid corrupting AsyncTask
* with our wrong handler to avoid creating bugs in the application code since we are
* a library.
*
* So make sure we execute the async task from UI thread to avoid any issue.
*/
HandlerUtils.runOnUiThread(new Runnable() {
@Override
public void run() {
sendLogs(groupState, stateSnapshot, batch, batchId);
}
});
}
use of com.microsoft.appcenter.ingestion.models.Log in project mobile-center-sdk-android by Microsoft.
the class DefaultLogSerializer method deserializeContainer.
@NonNull
@Override
public LogContainer deserializeContainer(@NonNull String json) throws JSONException {
JSONObject jContainer = new JSONObject(json);
LogContainer container = new LogContainer();
JSONArray jLogs = jContainer.getJSONArray(LOGS);
List<Log> logs = new ArrayList<>();
for (int i = 0; i < jLogs.length(); i++) {
JSONObject jLog = jLogs.getJSONObject(i);
Log log = readLog(jLog);
logs.add(log);
}
container.setLogs(logs);
return container;
}
Aggregations