private IndexOutputLog GetRecord(DictLog dictLog, string nameBase, string lineLog) { LineLog logData = new LineLog(); logData.ParseLine(lineLog, dictLog); logData.indexOutputLog.Base = nameBase; return(logData.indexOutputLog); }
public void ParseLine(string line, DictLog dictLog) { //1) Дата и время в формате "yyyyMMddHHmmss", легко превращается в дату функцией Дата(); //2) Статус транзакции – может принимать четыре значения "N" – "Отсутствует", "U" – "Зафиксирована", "R" – "Не завершена" и "C" – "Отменена"; //3) Транзакция в формате записи из двух элементов преобразованных в шестнадцатеричное число // – первый – число секунд с 01.01.0001 00:00:00 умноженное на 10000, // второй – номер транзакции; //4) Пользователь – указывается номер в массиве пользователей; //5) Компьютер – указывается номер в массиве компьютеров; //6) Приложение – указывается номер в массиве приложений; //7) Соединение – номер соединения; //8) Событие – указывается номер в массиве событий; //9) Важность – может принимать четыре значения – "I" – "Информация", "E" – "Ошибки", "W" – "Предупреждения" и "N" – "Примечания"; //10) Комментарий – любой текст в кавычках; //11) Метаданные – указывается номер в массиве метаданных; //12) Данные – самый хитрый элемент, содержащий вложенную запись; //13) Представление данных – текст в кавычках; //14) Сервер – указывается номер в массиве серверов; //15) Основной порт – указывается номер в массиве основных портов; //16) Вспомогательный порт – указывается номер в массиве вспомогательных портов; //17) Сеанс – номер сеанса; //18) Количество дополнительных метаданных, номера которых будут перечислены в следующих элементах записи. // Именно 18 - й элемент определяет длину записи, т.к.дальше будут следовать столько элементов сколько указано здесь +один последний, // назначение которого пока не определено и обычно там "{0}".Возможно это просто маркер окончания записи.Так же есть идея что {0} // похоже на пустой массив. // {20190729165108,N,{0,0},1,1,2,433,3,I,"",0,{"P",{6,{"S","jenkins"},{"S","ROSSKO\pavel.makarov"}}},"",1,1,0,1,0,{0}}, // {20190729165201,C,{2435928362a10,74c},1,1,2,433,5,I,\"\",0,{\"U\"},\"\",1,1,0,1,0,{0}}, // { 20190729165201,U,{ 2435928362a10,74c},1,1,2,433,6,I,"",45,{ "R",21:94e038d547ded5ea11e9af4b2d5a712d},"тест",1,1,0,1,0,{ 0} }, // {20190731120047,U,{2435984cb07f0,1dde2b},1,1,2,40,6,I,"",41,{"R",107:a49762e541d0f9ee11e2a921473faba2},"WMS_1NSK",1,1,0,1,0,{0}}, // {20190726083202,U,{243587bd5e620,154a},1,1,2,252,10,I,"",6,{"R",17:b3c300505699197f11e631d8d789bc5c},"Клементьев А.А. (Станционная, 16/1)",1,1,0,2,0,{0}}, // {20190812000019,N,{ 0,0},4,1,5,336800,10,I,"",247,{ "S","Отправка количества сканированийноменклатуры в сололайн"},"",1,1,0,1,0,{ 0}}, // {20190812114310,N,{ 0,0},2,1,4,10357,38,E,"{ОбщийМодуль.СобытийнаяМодельФронтПривилигерованный.Модуль(1670)}: При загрузке Маршрутный лист ОТГАГ012099 от 06.08.2019 0:00:00 не найден документ Заявка на возврат товаров от покупателя ОТГАГ046985 от 05.08.2019 17:29:03 ВызватьИсключение СообщениеОбОшибке;", // 0,{ "S","{""TypeDocument"": ""МаршрутныйЛист"",""Presentation"": ""Маршрутный лист ОТГАГ012099 от 06.08.2019 0:00:00"",""GUIDWithType"": ""{\""#\"",ba77c4fb-bed9-42ce-be5c-5e5a70a68369,228:ae5800505699b66311e9b7ae029cee1b}"",""GUID"": ""029cee1b-b7ae-11e9-ae58-00505699b663"",""DeletionMark"": false,""Unload"": true,""Comment"": ""tms 06.08.2019 1:22:50"",""Number"": ""ОТГАГ012099"",""DateTime"": ""2019-08-06T00:00:00"",""NumberKIS"": ""ОТГАГ012099"",""DateTimeKIS"": ""2019-08-06T00:00:00"",""Manager"": """",""WarehouseName"": ""Мск_Основной"",""WarehouseCode"": ""ОТ0000014"",""Driver"": ""Луньков Алексей Михайлович"",""TransportVehicle"": ""HYNDAI HD 72"",""Left"": true,""Delivered"": true,""RouteNumber"": ""03"",""RoutePoints"": [{""GUIDDocument"": ""{\""#\"",eddd79d8-809c-497f-9c4a-5943afddda98,195:ae5800505699b66311e9b4fc2cc5830d}"",""Presentation"": ""Реализация товаров и услуг ОТГАГ193609 от 02.08.2019 15:04:39"",""Status"": ""Доставлен"",""TypeDocument"": ""РеализацияТоваровУслуг"",""WarehouseName"": ""Мск_Основной"",""WarehouseCode"": ""ОТ0000014""},{""GUIDDocument"": ""{\""#\"",eddd79d8-809c-497f-9c4a-5943afddda98,195:ae5800505699b66311e9b74765f37017}"",""Presentation"": ""Реализация товаров и услуг ОТГАГ195398 от 05.08.2019 13:08:15"",""Status"": ""Доставлен"",""TypeDocument"": ""РеализацияТоваровУслуг"",""WarehouseName"": ""Мск_Основной"",""WarehouseCode"": ""ОТ0000014""}],""headers"": {""message_id"": ""7c3d54c5-bb3a-465e-8329-ce1f7b0a0c34"",""owner_id"": ""5ade20ac-b9e8-42dc-9003-4122957339e8"",""timestamp"": 1565610184883,""event_owner"": """"}}"}, // "",1,3,0,3376,0,{0}}, // {20191025103710,N,{0,0},369,6,1,499504,2,E,"Имя отчета: ""АнализПродаж""Установленные параметры:РазрешитьВсеФилиалы, значение: НетФилиалПоУмолчанию, значение: МассивПериод, значение: 25.10.2019 - 25.10.2019Установленные отборы:Ответственный, вид сравнения: Равно, значение: Семенов_Константин",0,{"U"},"",1,9,0,3925781,0,{0}}, string[] arrLine = ParseStringToArrayObject(line); string[] data = ParseStringToArrayObject(arrLine[11]); string dataObject = ""; // если символов 32 то это гуид объекта // иначае имя фонового задания if (data.Length > 1 && data[1] != null) { string patternUUID = "^[a-fA-F0-9]*:[a-fA-F0-9]{32}$"; Regex regex = new Regex(patternUUID); MatchCollection matches = regex.Matches(data[1]); if (matches.Count != 0) { dataObject = GetGUIDByUUID(data[1]); } else { dataObject = data[1]; } } this.indexOutputLog = new IndexOutputLog(); this.indexOutputLog.Timestamp = ConvertStringToDateTime(arrLine[0]); this.indexOutputLog.Transaction = GetStatusTransaction(arrLine[1]); this.indexOutputLog.User = DictLog.GetValueFromDictionaryLog(dictLog, arrLine[3], "user"); this.indexOutputLog.Computer = DictLog.GetValueFromDictionaryLog(dictLog, arrLine[4], "computer"); this.indexOutputLog.Application = DictLog.GetValueFromDictionaryLog(dictLog, arrLine[5], "application"); this.indexOutputLog.NumberConnection = int.Parse(arrLine[6].Length == 0 ? "0" : arrLine[6]); this.indexOutputLog.Event = LineLog.GetNameEvent(DictLog.GetValueFromDictionaryLog(dictLog, arrLine[7], "event")); this.indexOutputLog.Level = LineLog.GetLevel(arrLine[8]); this.indexOutputLog.Comment = arrLine[9].Trim('\"'); this.indexOutputLog.Metadata = DictLog.GetValueFromDictionaryLog(dictLog, arrLine[10], "metadata"); this.indexOutputLog.Presentation = arrLine[12].Trim('\"'); this.indexOutputLog.Server = DictLog.GetValueFromDictionaryLog(dictLog, arrLine[13], "server"); string strMainPort = DictLog.GetValueFromDictionaryLog(dictLog, arrLine[14], "mainPort"); this.indexOutputLog.MainPort = int.Parse(strMainPort.Length == 0 ? "0" : strMainPort); string strAdditionalPort = DictLog.GetValueFromDictionaryLog(dictLog, arrLine[16], "additionalPort"); this.indexOutputLog.AdditionalPort = int.Parse(strAdditionalPort.Length == 0 ? "0" : strAdditionalPort); this.indexOutputLog.NumberSession = int.Parse(arrLine[17].Length == 0 ? "0" : arrLine[17]); this.indexOutputLog.Data = dataObject; string[] dataTransaction = ParseStringToArrayObject(arrLine[2]); // дату транзакции пока опускаем //DateTime timestampTransaction = LineLog.getDateFromTimestamp1C(dataTransaction[0]); //if (timestampTransaction != new DateTime(1, 1, 1)) // this.indexOutputLog.Timestamp = timestampTransaction; this.indexOutputLog.NumberTransaction = Convert.ToInt64(dataTransaction[1], 16); }
public async Task ParseLineAsync(string line, DictLog dictLog) { await Task.Run(() => ParseLine(line, dictLog)).ConfigureAwait(true); }
private DateTime LogRecordProcessing(DictLog dictLog, StreamReader sreader , string nameBase, DateTime BoundaryPeriod) { string lineLog = ""; List <IndexOutputLog> listLine = new List <IndexOutputLog>(); string patternGUID = "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$"; Regex regex = new Regex(patternGUID); NumberRecordsProcessed = 0; System.Timers.Timer timer = new System.Timers.Timer(); timer.Interval = 60000; timer.Elapsed += new ElapsedEventHandler(onTimer); timer.Start(); while (!sreader.EndOfStream) { string line = sreader.ReadLine(); // заголовки пропускаем if ((line.Contains("1CV8LOG(ver 2.0)") || (regex.Matches(line).Count != 0) || line.Length == 0)) { continue; } // логи всегда будут склеиваться из нескольких строк if (lineLog.Length != 0 && ThisNewLineLog(line)) { // собрали строку лога, разберем ее try { IndexOutputLog record = GetRecord(dictLog, nameBase, lineLog); // пропустим обработанные строки if (record.Timestamp < BoundaryPeriod) { lineLog = line; continue; } //// обрабатываем только метаданные //if (record.Metadata.Length == 0) //{ // lineLog = line; // continue; //} listLine.Add(record); if (listLine.Count > settingsFile.NumberRecordsProcessedAtTime) { Task <DateTime> period = AddRecords(listLine); BoundaryPeriod = period.Result; NumberRecordsProcessed += listLine.Count; listLine.Clear(); } } catch (Exception e) { string error = e.Message + " record log:" + lineLog; Log.AddRecord("LogRecordProcessing", error); } lineLog = line; } else { lineLog += line; } } // обработаем хвост if (listLine.Count > 0) { Task <DateTime> period = AddRecords(listLine); BoundaryPeriod = period.Result; listLine.Clear(); NumberRecordsProcessed += listLine.Count; } timer.Dispose(); return(BoundaryPeriod); }
public void FromFileToElastic() { // прочитаем настройки settingsFile = new Settings(); settingsFile.Read(); if (!Directory.Exists(settingsFile.PathJournal)) { throw new Exception("Не найден каталог " + settingsFile.PathJournal); } SettingsReadBase settingsReadBase = new SettingsReadBase(); settingsReadBase.Read(); // прочитаем каталог баз Dictionary <string, string> arrayBase = DictLog.GetCatalogBase(settingsFile); nameIndex = settingsFile.NameIndexElastic + "-" + DateTime.Now.ToString("yyyyMMdd"); connectionSettings = new ConnectionSettings(new Uri("http://" + settingsFile.AdressElastic + ":" + settingsFile.PortElastic.ToString())); connectionSettings.DefaultIndex(nameIndex); // при указании идентификации используем ее if (settingsFile.ElasticUserName != null) { connectionSettings.BasicAuthentication(settingsFile.ElasticUserName, settingsFile.ElasticUserPassword); } elasticClient = new ElasticClient(connectionSettings); // добавить настройки кластера для создаваемых по умолчанию индексов // 0 реплик //elasticClient.Cluster.PutSettings(); // обойдем подкаталоги и прочитаем логи DirectoryInfo di = new DirectoryInfo(settingsFile.PathJournal); foreach (DirectoryInfo subDir in di.GetDirectories()) { // получим имя базы if (!arrayBase.ContainsKey(subDir.Name)) { continue; } string nameBase = arrayBase[subDir.Name]; // обойдем файлы foreach (DirectoryInfo subDirLog in subDir.GetDirectories()) { // для первого запуска берем общую дату DateTime LastBoundaryPeriod = LineLog.ConvertStringToDateTime(settingsReadBase.LastRunTime); // получим последнее время чтения if (settingsReadBase.LastTimeReadLogBase.ContainsKey(subDir.Name)) { LastBoundaryPeriod = LineLog.ConvertStringToDateTime(settingsReadBase.LastTimeReadLogBase[subDir.Name]); } else { settingsReadBase.LastTimeReadLogBase.Add(subDir.Name, LastBoundaryPeriod.ToString("yyyyMMddHHmmss")); } // получим словарь для разбора логов ЖР DictLog dictLog = DictLog.ParseDictionaryLog(subDirLog); // разберем лог ЖР foreach (FileInfo file in subDirLog.GetFiles("*.lgp")) { // обработаем файл // разрешаем запись другим потокам using (var fstream = new FileStream(file.FullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) using (StreamReader sreader = new StreamReader(fstream)) { // ранее обработанные файлы пропускаем // поскольку данные хранятся до секунды округляем время на начало секунды // чтобы не было постоянного повторного считывания DateTime LastWriteTime = file.LastWriteTime.AddMilliseconds(-file.LastWriteTime.Millisecond); if (LastWriteTime < LastBoundaryPeriod) { continue; } try { LastBoundaryPeriod = LogRecordProcessing(dictLog, sreader, nameBase, LastBoundaryPeriod); } catch (Exception e) { string error = e.Message; Log.AddRecord("LogRecordProcessing", error); } } } // некорректное сохранение часов, доделать settingsReadBase.LastTimeReadLogBase[subDir.Name] = LastBoundaryPeriod.ToString("yyyyMMddHHmmss"); } } // запишем настройки settingsFile.Write(); settingsReadBase.Write(); }
public static void addRecordDictLog(string[] arr, DictLog dictLog) { DictLog dict = new DictLog(); int arrCountRecord = arr.Count(); if (arrCountRecord == 3) { dict.Type = int.Parse(arr[0]); dict.Name = arr[1].Trim('"'); dict.Id = int.Parse(arr[2]); } else if (arrCountRecord == 4) { dict.Type = int.Parse(arr[0]); dict.Guid = arr[1]; dict.Name = arr[2].Trim('"'); dict.Id = int.Parse(arr[3]); } string id = dict.Id.ToString(); switch (dict.Type) { case 1: if (!dictLog.Users.ContainsKey(id)) { dictLog.Users.Add(id, dict.Name); } else { dictLog.Users[id] = dict.Name; } break; case 2: if (!dictLog.Computers.ContainsKey(id)) { dictLog.Computers.Add(id, dict.Name); } else { dictLog.Computers[id] = dict.Name; } break; case 3: if (!dictLog.Applications.ContainsKey(id)) { dictLog.Applications.Add(id, dict.Name); } else { dictLog.Applications[id] = dict.Name; } break; case 4: if (!dictLog.Events.ContainsKey(id)) { dictLog.Events.Add(id, dict.Name); } else { dictLog.Events[id] = dict.Name; } break; case 5: if (!dictLog.Metadata.ContainsKey(id)) { dictLog.Metadata.Add(id, dict.Name); } else { dictLog.Metadata[id] = dict.Name; } break; case 6: if (!dictLog.Servers.ContainsKey(id)) { dictLog.Servers.Add(id, dict.Name); } else { dictLog.Servers[id] = dict.Name; } break; case 7: if (!dictLog.MainPorts.ContainsKey(id)) { dictLog.MainPorts.Add(id, dict.Name); } else { dictLog.MainPorts[id] = dict.Name; } break; case 8: if (!dictLog.AdditionalPorts.ContainsKey(id)) { dictLog.AdditionalPorts.Add(id, dict.Name); } else { dictLog.AdditionalPorts[id] = dict.Name; } break; } }
public static DictLog ParseDictionaryLog(DirectoryInfo subDirLog) { DictLog dictLog = new DictLog(); // 6d184c14-f352-49bd-9baa-740acf9eca79 string patternGUID = "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$"; Regex regex = new Regex(patternGUID); // разберем словарь ЖР foreach (FileInfo file in subDirLog.GetFiles("*.lgf")) { // разрешаем запись другим потокам using (var fstream = new FileStream(file.FullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) using (StreamReader sreader_dict = new StreamReader(fstream)) { // первые 2 строки служебные // 1 тип лога 1CV8LOG(ver 2.0) // 2 идентификатор базы 28319a74-e5ca-487b-bd0d-c9207a1dc5f0 string lineDictLog = ""; while (!sreader_dict.EndOfStream) { string line = sreader_dict.ReadLine(); // заголовки пропускаем if (line.Contains("1CV8LOG(ver 2.0)") || (regex.Matches(line).Count != 0)) { continue; } //TODO: есть похожий метод в LogRecordProcessing, подумать над их объединением if (ThisNewLineDictLog(lineDictLog) && ThisEndLineDictLog(lineDictLog) && lineDictLog.Length != 0) { // собрали строку лога, разберем ее try { LineLog lineLog = new LineLog(); string[] arrLine = lineLog.ParseStringToArrayObject(lineDictLog); addRecordDictLog(arrLine, dictLog); // обработали прошлую строку, обновим чтоб текущая обработалась при следующей итерации lineDictLog = line; } catch (Exception e) { string error = e.Message + " record log:" + line; Log.AddRecord("DicLogProcessing", error); } } else { lineDictLog += line; } } // обработаем хвост if (lineDictLog.Length != 0) { try { LineLog lineLog = new LineLog(); string[] arrLine = lineLog.ParseStringToArrayObject(lineDictLog); addRecordDictLog(arrLine, dictLog); } catch (Exception e) { string error = e.Message + " record log:" + lineDictLog + "; Файл логов " + file.FullName; Log.AddRecord("DicLogProcessing", error); } } } } return(dictLog); }
public static string GetValueFromDictionaryLog(DictLog logDict, string value, string nameDictValue) { int? typeValue = null; string findValue = null; // поищем в кэше string hash = nameDictValue + value; logDict.Cache.TryGetValue(hash, out findValue); if (findValue != null) { return(findValue); } if (nameDictValue == "user") { typeValue = 1; logDict.Users.TryGetValue(value, out findValue); } else if (nameDictValue == "computer") { typeValue = 2; logDict.Computers.TryGetValue(value, out findValue); } else if (nameDictValue == "application") { typeValue = 3; logDict.Applications.TryGetValue(value, out findValue); } else if (nameDictValue == "event") { typeValue = 4; logDict.Events.TryGetValue(value, out findValue); } else if (nameDictValue == "metadata") { typeValue = 5; logDict.Metadata.TryGetValue(value, out findValue); } else if (nameDictValue == "server") { typeValue = 6; logDict.Servers.TryGetValue(value, out findValue); } else if (nameDictValue == "mainPort") { typeValue = 7; logDict.MainPorts.TryGetValue(value, out findValue); } else if (nameDictValue == "additionalPort") { typeValue = 8; logDict.AdditionalPorts.TryGetValue(value, out findValue); } // добавим в кэш if (!logDict.Cache.ContainsKey(hash)) { logDict.Cache.Add(hash, findValue); } if (typeValue == null) { return(""); } if (typeValue == 8) { return("0"); } //// linq потребляет много проца, заменил на поиск по словарям //int ivalue = int.Parse(value); //IEnumerable<DictLog> res = logDict.Where(s => s.Type == typeValue && s.Id == ivalue); //if (res.Count() != 0) //{ // findValue = res.First().Name; // Cache.Add(hash, findValue); // return findValue; //} return(""); }