Exemplo n.º 1
0
        /// <summary>
        /// Asynchronously retrieves logs from storage and flags them to avoid duplicate retrievals on subsequent calls
        /// </summary>
        /// <param name="channelName">Name of the channel to retrieve logs from</param>
        /// <param name="limit">The maximum number of logs to retrieve</param>
        /// <param name="logs">A list to which the retrieved logs will be added</param>
        /// <returns>A batch ID for the set of returned logs; null if no logs are found</returns>
        /// <exception cref="StorageException"/>
        public Task <string> GetLogsAsync(string channelName, int limit, List <Log> logs)
        {
            return(AddTaskToQueue(() =>
            {
                logs?.Clear();
                var retrievedLogs = new List <Log>();
                AppCenterLog.Debug(AppCenterLog.LogTag,
                                   $"Trying to get up to {limit} logs from storage for {channelName}");
                var idPairs = new List <Tuple <Guid?, long> >();
                var failedToDeserializeALog = false;
                var objectEntries = _storageAdapter.Select(TableName, ColumnChannelName, channelName, ColumnIdName, _pendingDbIdentifiers.Cast <object>().ToArray(), limit);
                var retrievedEntries = objectEntries.Select(entries =>
                                                            new LogEntry()
                {
                    Id = (long)entries[0],
                    Channel = (string)entries[1],
                    Log = (string)entries[2]
                }
                                                            ).ToList();
                foreach (var entry in retrievedEntries)
                {
                    try
                    {
                        var log = LogSerializer.DeserializeLog(entry.Log);
                        retrievedLogs.Add(log);
                        idPairs.Add(Tuple.Create(log.Sid, Convert.ToInt64(entry.Id)));
                    }
                    catch (JsonException e)
                    {
                        AppCenterLog.Error(AppCenterLog.LogTag, "Cannot deserialize a log in storage", e);
                        failedToDeserializeALog = true;
                        _storageAdapter.Delete(TableName, ColumnIdName, entry.Id);
                    }
                }
                if (failedToDeserializeALog)
                {
                    AppCenterLog.Warn(AppCenterLog.LogTag, "Deleted logs that could not be deserialized");
                }
                if (idPairs.Count == 0)
                {
                    AppCenterLog.Debug(AppCenterLog.LogTag,
                                       $"No available logs in storage for channel '{channelName}'");
                    return null;
                }

                // Process the results
                var batchId = Guid.NewGuid().ToString();
                ProcessLogIds(channelName, batchId, idPairs);
                logs?.AddRange(retrievedLogs);
                return batchId;
            }));
        }
 /// <summary>
 /// Reads an error log file from the given file.
 /// </summary>
 /// <param name="file">The file that contains error log.</param>
 /// <returns>An error log instance or null if the file doesn't contain an error log.</returns>
 public virtual ManagedErrorLog InstanceReadErrorLogFile(File file)
 {
     try
     {
         var errorLogString = file.ReadAllText();
         return((ManagedErrorLog)LogSerializer.DeserializeLog(errorLogString));
     }
     catch (System.Exception e)
     {
         AppCenterLog.Error(Crashes.LogTag, $"Encountered an unexpected error while reading an error log file: {file.Name}", e);
     }
     return(null);
 }
Exemplo n.º 3
0
        /// <summary>
        /// Asynchronously retrieves logs from storage and flags them to avoid duplicate retrievals on subsequent calls
        /// </summary>
        /// <param name="channelName">Name of the channel to retrieve logs from</param>
        /// <param name="limit">The maximum number of logs to retrieve</param>
        /// <param name="logs">A list to which the retrieved logs will be added</param>
        /// <returns>A batch ID for the set of returned logs; null if no logs are found</returns>
        /// <exception cref="StorageException"/>
        public Task <string> GetLogsAsync(string channelName, int limit, List <Log> logs)
        {
            return(AddTaskToQueue(() =>
            {
                logs?.Clear();
                var retrievedLogs = new List <Log>();
                AppCenterLog.Debug(AppCenterLog.LogTag,
                                   $"Trying to get up to {limit} logs from storage for {channelName}");
                var idPairs = new List <Tuple <Guid?, long> >();
                var failedToDeserializeALog = false;
                var retrievedEntries =
                    _storageAdapter.GetAsync <LogEntry>(entry => entry.Channel == channelName, limit)
                    .GetAwaiter().GetResult();
                foreach (var entry in retrievedEntries)
                {
                    if (_pendingDbIdentifiers.Contains(entry.Id))
                    {
                        continue;
                    }
                    try
                    {
                        var log = LogSerializer.DeserializeLog(entry.Log);
                        retrievedLogs.Add(log);
                        idPairs.Add(Tuple.Create(log.Sid, Convert.ToInt64(entry.Id)));
                    }
                    catch (JsonException e)
                    {
                        AppCenterLog.Error(AppCenterLog.LogTag, "Cannot deserialize a log in storage", e);
                        failedToDeserializeALog = true;
                        _storageAdapter.DeleteAsync <LogEntry>(row => row.Id == entry.Id)
                        .GetAwaiter().GetResult();
                    }
                }
                if (failedToDeserializeALog)
                {
                    AppCenterLog.Warn(AppCenterLog.LogTag, "Deleted logs that could not be deserialized");
                }
                if (idPairs.Count == 0)
                {
                    AppCenterLog.Debug(AppCenterLog.LogTag,
                                       $"No available logs in storage for channel '{channelName}'");
                    return null;
                }

                // Process the results
                var batchId = Guid.NewGuid().ToString();
                ProcessLogIds(channelName, batchId, idPairs);
                logs?.AddRange(retrievedLogs);
                return batchId;
            }));
        }
        /// <summary>
        /// Asynchronously retrieves logs from storage and flags them to avoid duplicate retrievals on subsequent calls
        /// </summary>
        /// <param name="channelName">Name of the channel to retrieve logs from</param>
        /// <param name="limit">The maximum number of logs to retrieve</param>
        /// <param name="logs">A list to which the retrieved logs will be added</param>
        /// <returns>A batch ID for the set of returned logs; null if no logs are found</returns>
        /// <exception cref="StorageException"/>
        public async Task <string> GetLogsAsync(string channelName, int limit, List <Log> logs)
        {
            var task = new Task <string>(() =>
            {
                logs?.Clear();
                var retrievedLogs = new List <Log>();
                MobileCenterLog.Debug(MobileCenterLog.LogTag,
                                      $"Trying to get up to {limit} logs from storage for {channelName}");
                var idPairs = new List <Tuple <Guid?, long> >();
                var failedToDeserializeALog = false;
                var retrievedEntries        =
                    _storageAdapter.GetAsync <LogEntry>(entry => entry.Channel == channelName, limit)
                    .Result;
                foreach (var entry in retrievedEntries)
                {
                    if (_pendingDbIdentifiers.Contains(entry.Id))
                    {
                        continue;
                    }
                    try
                    {
                        var log = LogSerializer.DeserializeLog(entry.Log);
                        retrievedLogs.Add(log);
                        idPairs.Add(Tuple.Create(log.Sid, Convert.ToInt64(entry.Id)));
                    }
                    catch (JsonException e)
                    {
                        MobileCenterLog.Error(MobileCenterLog.LogTag, "Cannot deserialize a log in storage", e);
                        failedToDeserializeALog = true;
                        _storageAdapter.DeleteAsync <LogEntry>(row => row.Id == entry.Id)
                        .Wait();
                    }
                }
                if (failedToDeserializeALog)
                {
                    MobileCenterLog.Warn(MobileCenterLog.LogTag, "Deleted logs that could not be deserialized");
                }
                if (idPairs.Count == 0)
                {
                    MobileCenterLog.Debug(MobileCenterLog.LogTag,
                                          $"No available logs in storage for channel '{channelName}'");
                    return(null);
                }

                // Process the results
                var batchId = Guid.NewGuid().ToString();
                ProcessLogIds(channelName, batchId, idPairs);
                logs?.AddRange(retrievedLogs);
                return(batchId);
            });

            try
            {
                _queue.Add(task);
            }
            catch (InvalidOperationException)
            {
                throw new StorageException("The operation has been cancelled");
            }

            _flushSemaphore.Release();
            return(await task.ConfigureAwait(false));
        }