示例#1
0
        private async Task <IReadOnlyCollection <PackageStatistics> > ParseLogEntries(ILeasedLogFile logFile)
        {
            var logStream = await OpenCompressedBlobAsync(logFile);

            var blobUri  = logFile.Uri;
            var blobName = logFile.Blob.Name;

            var packageStatistics = new List <PackageStatistics>();

            var stopwatch = Stopwatch.StartNew();

            try
            {
                // parse the log into table entities
                _jobEventSource.BeginningParseLog(blobUri);

                using (var logStreamReader = new StreamReader(logStream))
                {
                    do
                    {
                        var rawLogLine = logStreamReader.ReadLine();
                        if (rawLogLine != null)
                        {
                            var logEntry = CdnLogEntryParser.ParseLogEntryFromLine(rawLogLine);
                            if (logEntry != null)
                            {
                                var statistic = PackageStatisticsParser.FromCdnLogEntry(logEntry);
                                if (statistic != null)
                                {
                                    packageStatistics.Add(statistic);
                                }
                            }
                        }
                    } while (!logStreamReader.EndOfStream);
                }

                _jobEventSource.FinishingParseLog(blobUri, packageStatistics.Count);

                stopwatch.Stop();
                ApplicationInsights.TrackMetric("Blob parsing duration (ms)", stopwatch.ElapsedMilliseconds, blobName);
            }
            catch (Exception exception)
            {
                if (stopwatch.IsRunning)
                {
                    stopwatch.Stop();
                }

                _jobEventSource.FailedParseLog(blobUri);
                ApplicationInsights.TrackException(exception, blobName);
                throw;
            }
            finally
            {
                logStream.Dispose();
            }

            return(packageStatistics);
        }
示例#2
0
        private static string GetParsedModifiedLogEntry(string rawLogEntry)
        {
            var parsedEntry = CdnLogEntryParser.ParseLogEntryFromLine(rawLogEntry);

            if (parsedEntry == null)
            {
                return(null);
            }

            const string spaceCharacter = " ";
            const string dashCharacter  = "-";

            var stringBuilder = new StringBuilder();

            // timestamp
            stringBuilder.Append(ToUnixTimeStamp(parsedEntry.EdgeServerTimeDelivered) + spaceCharacter);
            // time-taken
            stringBuilder.Append((parsedEntry.EdgeServerTimeTaken.HasValue ? parsedEntry.EdgeServerTimeTaken.Value.ToString() : dashCharacter) + spaceCharacter);

            // REMOVE c-ip
            stringBuilder.Append(dashCharacter + spaceCharacter);

            // filesize
            stringBuilder.Append((parsedEntry.FileSize.HasValue ? parsedEntry.FileSize.Value.ToString() : dashCharacter) + spaceCharacter);
            // s-ip
            stringBuilder.Append((parsedEntry.EdgeServerIpAddress ?? dashCharacter) + spaceCharacter);
            // s-port
            stringBuilder.Append((parsedEntry.EdgeServerPort.HasValue ? parsedEntry.EdgeServerPort.Value.ToString() : dashCharacter) + spaceCharacter);
            // sc-status
            stringBuilder.Append((parsedEntry.CacheStatusCode ?? dashCharacter) + spaceCharacter);
            // sc-bytes
            stringBuilder.Append((parsedEntry.EdgeServerBytesSent.HasValue ? parsedEntry.EdgeServerBytesSent.Value.ToString() : dashCharacter) + spaceCharacter);
            // cs-method
            stringBuilder.Append((parsedEntry.HttpMethod ?? dashCharacter) + spaceCharacter);
            // cs-uri-stem
            stringBuilder.Append((parsedEntry.RequestUrl ?? dashCharacter) + spaceCharacter);

            // -
            stringBuilder.Append(dashCharacter + spaceCharacter);

            // rs-duration
            stringBuilder.Append((parsedEntry.RemoteServerTimeTaken.HasValue ? parsedEntry.RemoteServerTimeTaken.Value.ToString() : dashCharacter) + spaceCharacter);
            // rs-bytes
            stringBuilder.Append((parsedEntry.RemoteServerBytesSent.HasValue ? parsedEntry.RemoteServerBytesSent.Value.ToString() : dashCharacter) + spaceCharacter);
            // c-referrer
            stringBuilder.Append((parsedEntry.Referrer ?? dashCharacter) + spaceCharacter);
            // c-user-agent
            stringBuilder.Append((parsedEntry.UserAgent ?? dashCharacter) + spaceCharacter);
            // customer-id
            stringBuilder.Append((parsedEntry.CustomerId ?? dashCharacter) + spaceCharacter);
            // x-ec_custom-1
            stringBuilder.AppendLine((parsedEntry.CustomField ?? dashCharacter) + spaceCharacter);

            return(stringBuilder.ToString());
        }
            public void IgnoresLinesWithIncompleteDataWithOnErrorCallback()
            {
                // Act
                var logEntry = CdnLogEntryParser.ParseLogEntryFromLine(
                    LineNumber,
                    IncompleteDataLine,
                    IndexOutOfRangeExceptionOnError);

                // Assert
                Assert.Null(logEntry);
            }
 public void ThrowsExceptionForLinesWithIncorrectFormatDataWithoutOnErrorCallback()
 {
     // Act/Assert
     Assert.Throws <FormatException>(() =>
     {
         CdnLogEntryParser.ParseLogEntryFromLine(
             LineNumber,
             IncorrectFormatDataLine,
             null);
     });
 }
            public void IgnoresLinesWithIncorrectFormatDataWithOnErrorCallback()
            {
                // Act
                var logEntry = CdnLogEntryParser.ParseLogEntryFromLine(
                    LineNumber,
                    IncorrectFormatDataLine,
                    FormatExceptionOnError);

                // Assert
                Assert.Null(logEntry);
            }
 public void ThrowsExceptionForLinesWithIncompleteDataWithoutOnErrorCallback()
 {
     // Act/Assert
     Assert.Throws <IndexOutOfRangeException>(() =>
     {
         CdnLogEntryParser.ParseLogEntryFromLine(
             LineNumber,
             IncompleteDataLine,
             null);
     });
 }
            public void IgnoresNon200HttpStatusCodes(string status)
            {
                // Arrange
                var line = string.Format(StatusLineFormat, status);

                // Act
                var logEntry = CdnLogEntryParser.ParseLogEntryFromLine(
                    LineNumber,
                    line,
                    FailOnError);

                // Assert
                Assert.Null(logEntry);
            }
            public void DoesNotIgnore200LevelAndUnrecognizedHttpStatusCodes(string status)
            {
                // Arrange
                var line = string.Format(StatusLineFormat, status);

                // Act
                var logEntry = CdnLogEntryParser.ParseLogEntryFromLine(
                    LineNumber,
                    line,
                    (e, lineNumber) => Assert.False(true, "The error action should not be called."));

                // Assert
                Assert.NotNull(logEntry);
                Assert.Equal(status, logEntry.CacheStatusCode);
            }
            public void DoesNotIgnore200LevelAndUnrecognizedHttpStatusCodes(string status)
            {
                // Arrange
                var line = string.Format(StatusLineFormat, status);

                // Act
                var logEntry = CdnLogEntryParser.ParseLogEntryFromLine(
                    LineNumber,
                    line,
                    FailOnError);

                // Assert
                Assert.NotNull(logEntry);
                Assert.Equal(status, logEntry.CacheStatusCode);
            }
示例#10
0
        public void CdnLogEntryParserIntegration(string input)
        {
            var collector = new ChinaStatsCollector(
                Mock.Of <ILogSource>(),
                Mock.Of <ILogDestination>(),
                Mock.Of <ILogger <ChinaStatsCollector> >());

            var tranformedInput = collector.TransformRawLogLine(input);

            if (tranformedInput == null)
            {
                return;
            }
            string    output     = tranformedInput.ToString();
            const int lineNumber = 1;
            var       logEntry   = CdnLogEntryParser.ParseLogEntryFromLine(lineNumber, output, onErrorAction: null);

            Assert.Contains(tranformedInput.XEc_Custom_1, logEntry.CustomField);
            Assert.Contains(tranformedInput.CUserAgent, logEntry.UserAgent);
        }
        private async Task <CdnStatistics> ParseLogEntries(ILeasedLogFile logFile, IPackageStatisticsParser packageStatisticsParser, string fileName)
        {
            var logStream = await _statisticsBlobContainerUtility.OpenCompressedBlobAsync(logFile);

            var blobUri  = logFile.Uri;
            var blobName = logFile.BlobName;

            var packageStatistics = new List <PackageStatistics>();
            var toolStatistics    = new List <ToolStatistics>();

            var stopwatch = Stopwatch.StartNew();

            try
            {
                // parse the log into table entities
                _logger.LogInformation("Beginning to parse blob {FtpBlobUri}.", blobUri);

                using (var logStreamReader = new StreamReader(logStream))
                {
                    var lineNumber = 0;
                    do
                    {
                        var rawLogLine = logStreamReader.ReadLine();
                        if (rawLogLine != null)
                        {
                            lineNumber++;

                            var logEntry = CdnLogEntryParser.ParseLogEntryFromLine(
                                lineNumber,
                                rawLogLine,
                                (e, line) => _logger.LogError(
                                    LogEvents.FailedToParseLogFileEntry,
                                    e,
                                    LogMessages.ParseLogEntryLineFailed,
                                    fileName,
                                    line));

                            if (logEntry != null)
                            {
                                var statistic = packageStatisticsParser.FromCdnLogEntry(logEntry);
                                if (statistic != null)
                                {
                                    packageStatistics.Add(statistic);
                                }
                                else
                                {
                                    // check if this is a dist.nuget.org download
                                    if (logEntry.RequestUrl.Contains("dist.nuget.org/"))
                                    {
                                        var toolInfo = ToolStatisticsParser.FromCdnLogEntry(logEntry);
                                        if (toolInfo != null)
                                        {
                                            toolStatistics.Add(toolInfo);
                                        }
                                    }
                                }
                            }
                        }
                    } while (!logStreamReader.EndOfStream);
                }

                stopwatch.Stop();

                _logger.LogInformation("Finished parsing blob {FtpBlobUri} ({RecordCount} records).", blobUri, packageStatistics.Count);
                ApplicationInsightsHelper.TrackMetric("Blob parsing duration (ms)", stopwatch.ElapsedMilliseconds, blobName);
            }
            catch (Exception exception)
            {
                if (stopwatch.IsRunning)
                {
                    stopwatch.Stop();
                }

                _logger.LogError(LogEvents.FailedToParseLogFile, exception, "Failed to parse blob {FtpBlobUri}.", blobUri);
                ApplicationInsightsHelper.TrackException(exception, blobName);

                throw;
            }
            finally
            {
                logStream.Dispose();
            }

            return(new CdnStatistics(packageStatistics, toolStatistics));
        }
示例#12
0
        private async Task <CdnStatistics> ParseLogEntries(ILeasedLogFile logFile)
        {
            var logStream = await OpenCompressedBlobAsync(logFile);

            var blobUri  = logFile.Uri;
            var blobName = logFile.Blob.Name;

            var packageStatistics = new List <PackageStatistics>();
            var toolStatistics    = new List <ToolStatistics>();
            var dnxStatistics     = new List <DnxStatistics>();

            var stopwatch = Stopwatch.StartNew();

            try
            {
                // parse the log into table entities
                _jobEventSource.BeginningParseLog(blobUri);

                using (var logStreamReader = new StreamReader(logStream))
                {
                    do
                    {
                        var rawLogLine = logStreamReader.ReadLine();
                        if (rawLogLine != null)
                        {
                            var logEntry = CdnLogEntryParser.ParseLogEntryFromLine(rawLogLine);
                            if (logEntry != null)
                            {
                                var statistic = PackageStatisticsParser.FromCdnLogEntry(logEntry);
                                if (statistic != null)
                                {
                                    packageStatistics.Add(statistic);
                                }
                                else
                                {
                                    // check if this is a dist.nuget.org download
                                    if (logEntry.RequestUrl.Contains("dist.nuget.org/"))
                                    {
                                        var toolInfo = ToolStatisticsParser.FromCdnLogEntry(logEntry);
                                        if (toolInfo != null)
                                        {
                                            toolStatistics.Add(toolInfo);
                                        }
                                    }
                                    if (logEntry.RequestUrl.Contains("dist.asp.net"))
                                    {
                                        var dnxInfo = DnxStatisticsParser.FromCdnLogEntry(logEntry);
                                        if (dnxInfo != null)
                                        {
                                            dnxStatistics.Add(dnxInfo);
                                        }
                                    }
                                }
                            }
                        }
                    } while (!logStreamReader.EndOfStream);
                }

                _jobEventSource.FinishingParseLog(blobUri, packageStatistics.Count);

                stopwatch.Stop();
                ApplicationInsights.TrackMetric("Blob parsing duration (ms)", stopwatch.ElapsedMilliseconds, blobName);
            }
            catch (Exception exception)
            {
                if (stopwatch.IsRunning)
                {
                    stopwatch.Stop();
                }

                _jobEventSource.FailedParseLog(blobUri);
                ApplicationInsights.TrackException(exception, blobName);
                throw;
            }
            finally
            {
                logStream.Dispose();
            }

            var cdnStatistics = new CdnStatistics(packageStatistics, toolStatistics, dnxStatistics);

            return(cdnStatistics);
        }