Пример #1
0
        /// <summary>
        /// A factory method attempting to create an instance of entry out of array of fields as extracted from
        /// a single line in Storage Analytics Log file.
        /// </summary>
        /// <param name="fields">
        /// Array of string values of fields as extracted from a single line in a log file.
        /// It must not be null and should contain exactly 30 items.
        /// </param>
        /// <returns>A valid instance of <see cref="StorageAnalyticsLogEntry"/> if given fields match expected format,
        /// or null otherwise.</returns>
        public static StorageAnalyticsLogEntry TryParse(string[] fields)
        {
            Debug.Assert(fields != null);
            Debug.Assert(fields.Length == (int)StorageAnalyticsLogColumnId.LastColumn + 1);

            var entry = new StorageAnalyticsLogEntry();

            DateTime requestStartTime;

            if (!DateTime.TryParseExact(fields[(int)StorageAnalyticsLogColumnId.RequestStartTime], "o",
                                        CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out requestStartTime))
            {
                return(null);
            }
            entry.RequestStartTime = requestStartTime;

            StorageServiceType serviceType;

            if (Enum.TryParse <StorageServiceType>(fields[(int)StorageAnalyticsLogColumnId.ServiceType], true,
                                                   out serviceType))
            {
                entry.ServiceType = serviceType;

                StorageServiceOperationType operationType;
                if (Enum.TryParse <StorageServiceOperationType>(fields[(int)StorageAnalyticsLogColumnId.OperationType],
                                                                out operationType))
                {
                    entry.OperationType = operationType;
                }

                entry.RequestedObjectKey = fields[(int)StorageAnalyticsLogColumnId.RequestedObjectKey];
            }

            return(entry);
        }
        /// <summary>
        /// Given a log file (as a blob), parses it and return a collection of log entries matching version 1.0
        /// of the Storage Analytics Log Format.
        /// </summary>
        /// <param name="blob">Object representing a cloud blob with Storage Analytics log content.</param>
        /// <param name="cancellationToken">A token to monitor for cancellation request.</param>
        /// <returns>Collection of successfully parsed log entries.</returns>
        /// <exception cref="FormatException">If unable to parse a line in given log.</exception>
        /// <seealso cref="StorageAnalyticsLogEntry"/>
        /// <remarks>
        /// The method scans log file lines one at a time.
        /// First it attempts to detect a line format version and throws an exception if failed to do so.
        /// It skips all lines with version different than supported one, i.e. 1.0.
        /// Then it calls TryParseLogEntry to create a log entry out of every line of supported version and throws
        /// an exception if the parse method returns null.
        /// </remarks>
        public async Task <IEnumerable <StorageAnalyticsLogEntry> > ParseLogAsync(BlobBaseClient blob,
                                                                                  CancellationToken cancellationToken)
        {
            List <StorageAnalyticsLogEntry> entries = new List <StorageAnalyticsLogEntry>();

            using (Stream content = (await blob.DownloadAsync(cancellationToken).ConfigureAwait(false)).Value.Content)
            {
                using (TextReader tr = new StreamReader(content))
                {
                    for (int lineNumber = 1; ; lineNumber++)
                    {
                        cancellationToken.ThrowIfCancellationRequested();
                        string line = await tr.ReadLineAsync().ConfigureAwait(false);

                        if (line == null)
                        {
                            break;
                        }

                        Version version = TryParseVersion(line);
                        if (version == null)
                        {
                            string message = String.Format(CultureInfo.CurrentCulture,
                                                           "Unable to detect a version of log entry on line {1} of Storage Analytics log file '{0}'.",
                                                           blob.Name, lineNumber);

                            _logger.LogWarning(message);
                        }

                        if (version == supportedVersion)
                        {
                            StorageAnalyticsLogEntry entry = TryParseLogEntry(line);
                            if (entry == null)
                            {
                                string message = String.Format(CultureInfo.CurrentCulture,
                                                               "Unable to parse the log entry on line {1} of Storage Analytics log file '{0}'.",
                                                               blob.Name, lineNumber);

                                _logger.LogWarning(message);
                            }

                            entries.Add(entry);
                        }
                    }
                }
            }

            return(entries);
        }
        /// <summary>
        /// Attempts to parse a single line of Storage Analytics Log file using Regex matches.
        /// </summary>
        /// <param name="line">A line as extracted from a Storage Analytics Log file. Must not be null or empty.</param>
        /// <returns>Parsed instance of <see cref="StorageAnalyticsLogEntry"/> if the given line matches expected format
        /// of the Storage Analytics Log v1.0, or null otherwise.</returns>
        public StorageAnalyticsLogEntry TryParseLogEntry(string line)
        {
            Debug.Assert(line != null);

            var capturedFields =
                from Match m in _compiledRegex.Matches(line)
                select WebUtility.HtmlDecode(m.Groups[1].Value);

            string[] fieldsArray = capturedFields.ToArray();

            if (fieldsArray.Length != ColumnCount)
            {
                return(null);
            }

            return(StorageAnalyticsLogEntry.TryParse(fieldsArray));
        }
Пример #4
0
        /// <summary>
        /// Given a log file (as a blob), parses it and return a collection of log entries matching version 1.0
        /// of the Storage Analytics Log Format.
        /// </summary>
        /// <param name="blob">Object representing a cloud blob with Storage Analytics log content.</param>
        /// <param name="cancellationToken">A token to monitor for cancellation request.</param>
        /// <returns>Collection of successfully parsed log entries.</returns>
        /// <exception cref="FormatException">If unable to parse a line in given log.</exception>
        /// <seealso cref="StorageAnalyticsLogEntry"/>
        /// <remarks>
        /// The method scans log file lines one at a time.
        /// First it attempts to detect a line format version and throws an exception if failed to do so.
        /// It skips all lines with version different than supported one, i.e. 1.0.
        /// Then it calls TryParseLogEntry to create a log entry out of every line of supported version and throws
        /// an exception if the parse method returns null.
        /// </remarks>
        public async Task <IEnumerable <StorageAnalyticsLogEntry> > ParseLogAsync(ICloudBlob blob,
                                                                                  CancellationToken cancellationToken)
        {
            List <StorageAnalyticsLogEntry> entries = new List <StorageAnalyticsLogEntry>();

            using (TextReader tr = new StreamReader(await blob.OpenReadAsync(cancellationToken)))
            {
                for (int lineNumber = 1; ; lineNumber++)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    string line = await tr.ReadLineAsync();

                    if (line == null)
                    {
                        break;
                    }

                    Version version = TryParseVersion(line);
                    if (version == null)
                    {
                        string message = String.Format(CultureInfo.CurrentCulture,
                                                       "Unable to detect a version of log entry on line {1} of Storage Analytics log file '{0}'.",
                                                       blob.Name, lineNumber);
                        throw new FormatException(message);
                    }

                    if (version == supportedVersion)
                    {
                        StorageAnalyticsLogEntry entry = TryParseLogEntry(line);
                        if (entry == null)
                        {
                            string message = String.Format(CultureInfo.CurrentCulture,
                                                           "Unable to parse the log entry on line {1} of Storage Analytics log file '{0}'.",
                                                           blob.Name, lineNumber);
                            throw new FormatException(message);
                        }

                        entries.Add(entry);
                    }
                }
            }

            return(entries);
        }
        private static StorageAnalyticsLogEntry CreateEntry(string requestStartTime, StorageServiceOperationType operationType, StorageServiceType serviceType, string requestedObjectKey)
        {
            StorageAnalyticsLogEntry entry = new StorageAnalyticsLogEntry();
            entry.RequestStartTime = DateTime.Parse(requestStartTime, CultureInfo.InvariantCulture);
            entry.OperationType = operationType;
            entry.ServiceType = serviceType;
            entry.RequestedObjectKey = requestedObjectKey;

            return entry;
        }
        /// <summary>
        /// A factory method attempting to create an instance of entry out of array of fields as extracted from
        /// a single line in Storage Analytics Log file.
        /// </summary>
        /// <param name="fields">
        /// Array of string values of fields as extracted from a single line in a log file. 
        /// It must not be null and should contain exactly 30 items.
        /// </param>
        /// <returns>A valid instance of <see cref="StorageAnalyticsLogEntry"/> if given fields match expected format,
        /// or null otherwise.</returns>
        public static StorageAnalyticsLogEntry TryParse(string[] fields)
        {
            Debug.Assert(fields != null);
            Debug.Assert(fields.Length == (int)StorageAnalyticsLogColumnId.LastColumn + 1);

            var entry = new StorageAnalyticsLogEntry();

            DateTime requestStartTime;
            if (!DateTime.TryParseExact(fields[(int)StorageAnalyticsLogColumnId.RequestStartTime], "o", 
                CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out requestStartTime))
            {
                return null;
            }
            entry.RequestStartTime = requestStartTime;

            StorageServiceType serviceType;
            if (Enum.TryParse<StorageServiceType>(fields[(int)StorageAnalyticsLogColumnId.ServiceType], true,
                out serviceType))
            {
                entry.ServiceType = serviceType;

                StorageServiceOperationType operationType;
                if (Enum.TryParse<StorageServiceOperationType>(fields[(int)StorageAnalyticsLogColumnId.OperationType],
                out operationType))
                {
                    entry.OperationType = operationType;
                }

                entry.RequestedObjectKey = fields[(int)StorageAnalyticsLogColumnId.RequestedObjectKey];
            }

            return entry;
        }