Exemplo n.º 1
0
        public void TestOnLogFileProduced()
        {
            string logFile          = Path.Combine(Path.GetTempPath(), GetRandomFileName());
            int    maxFileSize      = 1; // max file size of 1 means every line will go to a new file
            int    messageCount     = 5; // number of messages to log
            var    reportedLogFiles = new List <string>();

            using (var log = new CsvFileLog(logFile, new[] { CsvFileLog.ColumnKind.Message }, maxFileSize: maxFileSize))
            {
                log.OnLogFileProduced += (path) => reportedLogFiles.Add(path);
                for (int i = 0; i < messageCount; i++)
                {
                    log.Write(TestTimestamp, TestThreadId, TestSeverity, i.ToString());
                }
            }

            // assert that a log file was reported for each line
            reportedLogFiles.Count.Should().Be(messageCount);

            // assert the content of each log file
            for (int i = 0; i < messageCount; i++)
            {
                var expected = $"\"{i}\"{Environment.NewLine}";
                File.ReadAllText(reportedLogFiles[i]).Should().BeEquivalentTo(expected);
            }
        }
Exemplo n.º 2
0
        private string RenderMessage(CsvFileLog log, string message)
        {
            var sb = new StringBuilder();

            log.RenderMessage(sb, TestTimestamp, TestThreadId, TestSeverity, message);
            return(sb.ToString());
        }
Exemplo n.º 3
0
        public void TestRenderSchema(CsvFileLog.ColumnKind column, int columnIndex, int columnCount)
        {
            string logFile = Path.Combine(Path.GetTempPath(), GetRandomFileName());

            // schema:
            //   <empty>,...,<empty>,<column>,<empty>,...,<empty>
            // where
            //   - <column> is at position 'columnIndex'
            //   - total number of columns is 'columnCount'
            var schema =
                Repeat(CsvFileLog.ColumnKind.Empty, columnIndex - 1)
                .Concat(new[] { column })
                .Concat(Repeat(CsvFileLog.ColumnKind.Empty, columnCount - columnIndex - 1));

            using (var log = new CsvFileLog(logFile, schema, serviceName: "CsvFileLogTests"))
            {
                var actual   = RenderMessage(log, TestMessage);
                var expected = string.Join(",", schema
                                           .Select(col => RenderColumn(log, col, TestMessage))
                                           .Select(str => '"' + str + '"'));
                actual.Should().BeEquivalentTo(expected);
            }

            IEnumerable <CsvFileLog.ColumnKind> Repeat(CsvFileLog.ColumnKind col, int count)
            {
                return(Enumerable.Range(0, Math.Max(0, count)).Select(_ => col));
            }
        }
Exemplo n.º 4
0
        Logger()
        {
            int limit;

            int.TryParse(ConfigurationManager.AppSettings["Log Limit"], out limit);
            string logTypeValue = ConfigurationManager.AppSettings["Log Type"];

            switch (logTypeValue)
            {
            case "CSV":
                Log = new CsvFileLog(limit);
                break;

            case "Encrypted CSV":
                Log = new EncryptedCsvFileLog(limit);
                break;

            case "Event Log":
                Log = new EventLog();
                break;

            default:
                throw new NoLogDefinedException("The log file is not defined in the config file");
            }
        }
Exemplo n.º 5
0
        public void TestDontRenderConstColumns(string schema, string expectedFileSchema, string expectedConstSchema)
        {
            var constCol = CsvFileLog.ColumnKind.BuildId;
            var dynCol   = CsvFileLog.ColumnKind.Message;

            var csvLog = new CsvFileLog(
                GetRandomLogFile(),
                schema: TranslateSchema(schema),
                renderConstColums: false);

            csvLog.IsConstValueColumn(constCol).Should().BeTrue();
            csvLog.IsConstValueColumn(dynCol).Should().BeFalse();

            csvLog.FileSchema.Should().BeEquivalentTo(TranslateSchema(expectedFileSchema));
            csvLog.ConstSchema.Should().BeEquivalentTo(TranslateSchema(expectedConstSchema));

            CsvFileLog.ColumnKind[] TranslateSchema(string s)
            {
                return(s
                       .Split(',')
                       .Select(c => c.Trim())
                       .Where(c => !string.IsNullOrEmpty(c))
                       .Select(TranslateCol)
                       .ToArray());
            }

            CsvFileLog.ColumnKind TranslateCol(string c)
            {
                Assert.True(c == "D" || c == "C", $"Column specified must be either 'C' or 'D', but is '{c}'");
                return(c == "D" ? dynCol : constCol);
            }
        }
Exemplo n.º 6
0
        [InlineData("1\n3", "\"1\n3\"")]   // a new line may appear in a message
        public void TestRenderMessageColumn(string message, string expected)
        {
            string logFile = Path.Combine(Path.GetTempPath(), GetRandomFileName());

            using (var log = new CsvFileLog(logFile, new[] { CsvFileLog.ColumnKind.Message }))
            {
                var actual = RenderMessage(log, message);
                actual.Should().BeEquivalentTo(expected);
            }
        }
Exemplo n.º 7
0
        private static async Task WithLoggerAsync(Func <ILogger, Task> action, string?logFilePath)
        {
            CsvFileLog?csvFileLog = null;
            ConsoleLog?consoleLog = null;
            Logger?    logger     = null;

            try
            {
                if (!string.IsNullOrEmpty(logFilePath))
                {
                    // Needed to satisfy the type checker
                    Contract.AssertNotNull(logFilePath);

                    if (string.IsNullOrEmpty(Path.GetDirectoryName(logFilePath)))
                    {
                        var cwd = Directory.GetCurrentDirectory();
                        logFilePath = Path.Combine(cwd, logFilePath);
                    }

                    csvFileLog = new CsvFileLog(logFilePath, new List <CsvFileLog.ColumnKind>()
                    {
                        CsvFileLog.ColumnKind.PreciseTimeStamp,
                        CsvFileLog.ColumnKind.ProcessId,
                        CsvFileLog.ColumnKind.ThreadId,
                        CsvFileLog.ColumnKind.LogLevel,
                        CsvFileLog.ColumnKind.LogLevelFriendly,
                        CsvFileLog.ColumnKind.Message,
                    });
                }

                consoleLog = new ConsoleLog(useShortLayout: false, printSeverity: true);

                var logs = new ILog?[] { csvFileLog, consoleLog };
                logger = new Logger(logs.Where(log => log != null).Cast <ILog>().ToArray());

                await action(logger);
            }
            finally
            {
                logger?.Dispose();
                csvFileLog?.Dispose();
                consoleLog?.Dispose();
            }
        }
Exemplo n.º 8
0
 Logger()
 {
     int limit;
     int.TryParse(ConfigurationManager.AppSettings["Log Limit"], out limit);
     string logTypeValue = ConfigurationManager.AppSettings["Log Type"];
     switch (logTypeValue)
     {
         case "CSV":
             Log = new CsvFileLog(limit);
             break;
         case "Encrypted CSV":
             Log = new EncryptedCsvFileLog(limit);
             break;
         case "Event Log":
             Log = new EventLog();
             break;
         default:
             throw new NoLogDefinedException("The log file is not defined in the config file");
     }
 }
Exemplo n.º 9
0
        private void EnableRemoteTelemetryIfNeeded(string logFilePath)
        {
            if (!_enableRemoteTelemetry)
            {
                return;
            }

            if (_kustoUploader == null)
            {
                _logger.Warning
                (
                    "Remote telemetry flag is enabled but no Kusto connection string was found in environment variable '{0}'",
                    KustoConnectionStringEnvVarName
                );
                return;
            }

            _csvFileLog = new CsvFileLog
                          (
                logFilePath: logFilePath + TmpCsvLogFileExt,
                serviceName: ServiceName,
                schema: KustoTableCsvSchema,
                severity: _fileLogSeverity,
                maxFileSize: _csvLogMaxFileSize
                          );

            // Every time a log file written to disk and closed, we rename it and upload it to Kusto.
            // The last log file will be produced when _csvFileLog is disposed, so _kustUploader better
            // not be disposed before _csvFileLog.
            _csvFileLog.OnLogFileProduced += (path) =>
            {
                string newPath = Path.ChangeExtension(path, CsvLogFileExt);
                File.Move(path, newPath);
                _kustoUploader.PostFileForUpload(newPath, _csvFileLog.BuildId);
            };

            _logger.AddLog(_csvFileLog);
            _logger.Always("Remote telemetry enabled");
        }
Exemplo n.º 10
0
        private void EnableRemoteTelemetryIfNeeded(string logFilePath)
        {
            if (!_enableRemoteTelemetry)
            {
                return;
            }

            var kustoConnectionString = Environment.GetEnvironmentVariable(KustoConnectionStringEnvVarName);

            if (string.IsNullOrWhiteSpace(kustoConnectionString))
            {
                _logger.Warning
                (
                    "Remote telemetry flag is enabled but no Kusto connection string was found in environment variable '{0}'",
                    KustoConnectionStringEnvVarName
                );
                return;
            }

            _csvFileLog = new CsvFileLog
                          (
                logFilePath: logFilePath + TmpCsvLogFileExt,
                serviceName: ServiceName,
                schema: KustoTableCsvSchema,
                renderConstColums: false,
                severity: _fileLogSeverity,
                maxFileSize: _csvLogMaxFileSize
                          );

            var indexedColumns = _csvFileLog.FileSchema.Select((col, idx) => new CsvColumnMapping {
                ColumnName = col.ToString(), Ordinal = idx
            });
            var constColumns = _csvFileLog.ConstSchema.Select(col => new CsvColumnMapping {
                ColumnName = col.ToString(), ConstValue = _csvFileLog.RenderConstColumn(col)
            });
            var csvMapping = indexedColumns.Concat(constColumns).ToArray();

            var csvMappingStr = string.Join("", csvMapping.Select(col => $"{Environment.NewLine}  Name: '{col.ColumnName}', ConstValue: '{col.ConstValue}', Ordinal: {col.Ordinal}"));

            _logger.Always("Using csv mapping:{0}", csvMappingStr);

            _kustoUploader = new KustoUploader
                             (
                kustoConnectionString,
                database: KustoDatabase,
                table: KustoTable,
                csvMapping: csvMapping,
                deleteFilesOnSuccess: true,
                checkForIngestionErrors: true,
                log: _consoleLog
                             );

            // Every time a log file written to disk and closed, we rename it and upload it to Kusto.
            // The last log file will be produced when _csvFileLog is disposed, so _kustUploader better
            // not be disposed before _csvFileLog.
            _csvFileLog.OnLogFileProduced += (path) =>
            {
                string newPath = Path.ChangeExtension(path, CsvLogFileExt);
                File.Move(path, newPath);
                _kustoUploader.PostFileForUpload(newPath, _csvFileLog.BuildId);
            };

            _logger.AddLog(_csvFileLog);
            _logger.Always("Remote telemetry enabled");
        }
Exemplo n.º 11
0
 private string RenderColumn(CsvFileLog log, CsvFileLog.ColumnKind col, string message)
 {
     return(log.RenderColumn(col, TestTimestamp, TestThreadId, TestSeverity, message));
 }
Exemplo n.º 12
0
        public void TestParseTableSchema(string schema, CsvFileLog.ColumnKind[] expected)
        {
            var actual = CsvFileLog.ParseTableSchema(schema);

            actual.Should().BeEquivalentTo(expected);
        }