Исправлена ошибка с некорреткной обработикой строк. Добавлена обработка одного файла. Косметические изменения.
parent
4ea4246b41
commit
38c7a53129
|
@ -65,6 +65,8 @@ Usage of /tmp/go-build847101717/b001/exe/log-processor:
|
||||||
Задержка чтения входного файла. Разрешены обозначения 'ns', 'us' ('µs'), 'ms', 's', 'm','h') (default "5ms")
|
Задержка чтения входного файла. Разрешены обозначения 'ns', 'us' ('µs'), 'ms', 's', 'm','h') (default "5ms")
|
||||||
-tz-offset string
|
-tz-offset string
|
||||||
Сдвиг по времени от UTC (default "+03:00")
|
Сдвиг по времени от UTC (default "+03:00")
|
||||||
|
-worklog-out string
|
||||||
|
Направление вывода журнала работы программы (console, file) (default "file")
|
||||||
-write-out-file
|
-write-out-file
|
||||||
Запись обработанных данных в файл
|
Запись обработанных данных в файл
|
||||||
```
|
```
|
||||||
|
|
|
@ -3,8 +3,7 @@
|
||||||
// Версия: 1.0.0
|
// Версия: 1.0.0
|
||||||
// Автор: Сергей Калинин svk@nuk-svk.ru https://git.nuk-svk.ru/svk/
|
// Автор: Сергей Калинин svk@nuk-svk.ru https://git.nuk-svk.ru/svk/
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
// Лицензия: GPL(v3)
|
|
||||||
//------------------------- ------------------------------------------------
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -16,11 +15,11 @@ import (
|
||||||
"time"
|
"time"
|
||||||
"io"
|
"io"
|
||||||
// "runtime"
|
// "runtime"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"strconv"
|
"strconv"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
// "github.com/hpcloud/tail"
|
// "github.com/hpcloud/tail"
|
||||||
"net"
|
"net"
|
||||||
"sort"
|
"sort"
|
||||||
|
@ -66,6 +65,8 @@ var (
|
||||||
TailSleep time.Duration
|
TailSleep time.Duration
|
||||||
RunAsWinService bool
|
RunAsWinService bool
|
||||||
ExcludeEvent []string
|
ExcludeEvent []string
|
||||||
|
InFile string
|
||||||
|
WorkLogOut string
|
||||||
)
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
|
@ -332,6 +333,7 @@ func getNewFilesFromDir(filesList []string, dir string) []string {
|
||||||
// from the input buffered reader.
|
// from the input buffered reader.
|
||||||
// An error is returned iff there is an error with the
|
// An error is returned iff there is an error with the
|
||||||
// buffered reader.
|
// buffered reader.
|
||||||
|
|
||||||
func Readln(r *bufio.Reader) (string, error) {
|
func Readln(r *bufio.Reader) (string, error) {
|
||||||
var (isPrefix bool = true
|
var (isPrefix bool = true
|
||||||
err error = nil
|
err error = nil
|
||||||
|
@ -344,6 +346,13 @@ func Readln(r *bufio.Reader) (string, error) {
|
||||||
return string(ln),err
|
return string(ln),err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// func Readln(r *bufio.Reader) (string, error){
|
||||||
|
// result, err := r.ReadString('\n')
|
||||||
|
// // log.Println(result)
|
||||||
|
// ln := result
|
||||||
|
// return ln, err
|
||||||
|
// }
|
||||||
|
|
||||||
func hex2int(hexStr string) int {
|
func hex2int(hexStr string) int {
|
||||||
// base 16 for hexadecimal
|
// base 16 for hexadecimal
|
||||||
result, err := strconv.ParseInt(hexStr, 16, 64)
|
result, err := strconv.ParseInt(hexStr, 16, 64)
|
||||||
|
@ -698,9 +707,9 @@ func parseString (outLine string, logOffset int64) map[string]string {
|
||||||
regexpLogRecord := regexp.MustCompile(`(?P<DateTime>\d{14}),(?P<TranStatus>\w{1}),\{(?P<TranDuration>\w+),(?P<TranNumber>\w+)\},(?P<Usr>\d+),(?P<ComputerName>\d+),(?P<ApplicationName>\d+),(?P<ConnectionID>\d+),(?P<Event>\d+),(?P<Importance>\w{1}),\"(?P<Comment>.*)\",(?P<Metadata>\d+),\{(?P<Data>.+)\},\"(?P<PresentData>.*)\",(?P<Server>\d+),(?P<Port>\d+),(?P<AddPort>\d+),(?P<SessionID>\d+),(?P<OtherData1>\d{1}),\{(\d|,)+\}$`)
|
regexpLogRecord := regexp.MustCompile(`(?P<DateTime>\d{14}),(?P<TranStatus>\w{1}),\{(?P<TranDuration>\w+),(?P<TranNumber>\w+)\},(?P<Usr>\d+),(?P<ComputerName>\d+),(?P<ApplicationName>\d+),(?P<ConnectionID>\d+),(?P<Event>\d+),(?P<Importance>\w{1}),\"(?P<Comment>.*)\",(?P<Metadata>\d+),\{(?P<Data>.+)\},\"(?P<PresentData>.*)\",(?P<Server>\d+),(?P<Port>\d+),(?P<AddPort>\d+),(?P<SessionID>\d+),(?P<OtherData1>\d{1}),\{(\d|,)+\}$`)
|
||||||
// Полную строку прогоняем через регексп и распихиваем сразу по полям
|
// Полную строку прогоняем через регексп и распихиваем сразу по полям
|
||||||
matchedOut := regexpLogRecord.MatchString(outLine)
|
matchedOut := regexpLogRecord.MatchString(outLine)
|
||||||
if Debug {
|
// if Debug {
|
||||||
log.Println(outLine)
|
// log.Println(outLine)
|
||||||
}
|
// }
|
||||||
if matchedOut {
|
if matchedOut {
|
||||||
findedData := regexpLogRecord.FindStringSubmatch(outLine)
|
findedData := regexpLogRecord.FindStringSubmatch(outLine)
|
||||||
if findedData != nil {
|
if findedData != nil {
|
||||||
|
@ -811,12 +820,18 @@ func implContains(sl []string, name string) bool {
|
||||||
|
|
||||||
// Запуск чтения файлов
|
// Запуск чтения файлов
|
||||||
func runOperations () {
|
func runOperations () {
|
||||||
|
var client *opensearch.Client
|
||||||
|
|
||||||
|
if InFile != "" {
|
||||||
|
tail(client, InFile, os.Stdout)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// получаем список файлов на момент запуска
|
// получаем список файлов на момент запуска
|
||||||
filesList := getDirectoryContents(DirIn)
|
filesList := getDirectoryContents(DirIn)
|
||||||
// получаем последний модифицированный файл
|
// получаем последний модифицированный файл
|
||||||
lastModifyFiles := getLastModifyFile(DirIn)
|
lastModifyFiles := getLastModifyFile(DirIn)
|
||||||
|
|
||||||
var client *opensearch.Client
|
|
||||||
log.Println("Список новых файлов:", lastModifyFiles, len(lastModifyFiles))
|
log.Println("Список новых файлов:", lastModifyFiles, len(lastModifyFiles))
|
||||||
// запускаем процесс обработки
|
// запускаем процесс обработки
|
||||||
if len(lastModifyFiles) == 0 {
|
if len(lastModifyFiles) == 0 {
|
||||||
|
@ -876,6 +891,7 @@ func tail(client *opensearch.Client, fileName string, out io.Writer) {
|
||||||
// bulkCount int
|
// bulkCount int
|
||||||
// arrRecords []map[string]string
|
// arrRecords []map[string]string
|
||||||
fOut *os.File
|
fOut *os.File
|
||||||
|
// matchedEnd bool
|
||||||
)
|
)
|
||||||
|
|
||||||
// bulkCount = 0
|
// bulkCount = 0
|
||||||
|
@ -924,9 +940,11 @@ func tail(client *opensearch.Client, fileName string, out io.Writer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
oldSize := info.Size()
|
oldSize := info.Size()
|
||||||
|
|
||||||
|
// Регулярные выражения для определения начала и конца записи
|
||||||
regexpBeginRecord := regexp.MustCompile(`^\{\d{14},\w{1},$`)
|
regexpBeginRecord := regexp.MustCompile(`^\{\d{14},\w{1},$`)
|
||||||
regexpEndRecord := regexp.MustCompile(`^\},$`)
|
regexpEndRecord := regexp.MustCompile(`^\},$`)
|
||||||
// var (
|
// var (й
|
||||||
// isPrefix bool = true
|
// isPrefix bool = true
|
||||||
// // err error = nil
|
// // err error = nil
|
||||||
// line []byte
|
// line []byte
|
||||||
|
@ -947,18 +965,20 @@ func tail(client *opensearch.Client, fileName string, out io.Writer) {
|
||||||
matchedBegin := regexpBeginRecord.MatchString(l)
|
matchedBegin := regexpBeginRecord.MatchString(l)
|
||||||
if matchedBegin {
|
if matchedBegin {
|
||||||
recBegin = true
|
recBegin = true
|
||||||
|
outLine = ""
|
||||||
}
|
}
|
||||||
if recBegin {
|
if recBegin {
|
||||||
outLine = outLine + l
|
outLine = outLine + l
|
||||||
// outLine = outLine + strings.TrimSpace(l)
|
|
||||||
}
|
}
|
||||||
// Находим конец записи
|
// Находим конец записи
|
||||||
matchedEnd := regexpEndRecord.MatchString(l)
|
matchedEnd := regexpEndRecord.MatchString(l)
|
||||||
// fmt.Println(recBegin, matchedEnd)
|
|
||||||
// fmt.Println(outLine)
|
|
||||||
if matchedEnd {
|
if matchedEnd {
|
||||||
recBegin = false
|
recBegin = false
|
||||||
outLine = strings.TrimSuffix(strings.TrimLeft(outLine, "{,"), "},")
|
outLine = strings.TrimSuffix(strings.TrimLeft(outLine, "{,"), "},")
|
||||||
|
if Debug {
|
||||||
|
log.Println(outLine)
|
||||||
|
}
|
||||||
// Парсим подготовленную строку
|
// Парсим подготовленную строку
|
||||||
result := parseString(outLine, logOffset)
|
result := parseString(outLine, logOffset)
|
||||||
if Debug {
|
if Debug {
|
||||||
|
@ -1012,6 +1032,12 @@ func tail(client *opensearch.Client, fileName string, out io.Writer) {
|
||||||
log.Println("Ошибка определения позиции 'pos, err := f.Seek(0, io.SeekCurrent)' в файле", fileName, "error:", err)
|
log.Println("Ошибка определения позиции 'pos, err := f.Seek(0, io.SeekCurrent)' в файле", fileName, "error:", err)
|
||||||
// panic(err)
|
// panic(err)
|
||||||
}
|
}
|
||||||
|
// Если задан файл с коммандной строки то выходим
|
||||||
|
if InFile != "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Запускаем чтение каталога и получепние списка с новыми файлами
|
||||||
for {
|
for {
|
||||||
time.Sleep(time.Second)
|
time.Sleep(time.Second)
|
||||||
newinfo, err := f.Stat()
|
newinfo, err := f.Stat()
|
||||||
|
@ -1302,11 +1328,11 @@ func main() {
|
||||||
flag.StringVar(&DirCfg, "dir-config", ".config", "Каталог для файлов настройки (DIR_CFG)")
|
flag.StringVar(&DirCfg, "dir-config", ".config", "Каталог для файлов настройки (DIR_CFG)")
|
||||||
flag.StringVar(&FileCfg, "config", "config.ini", "Файл настроек")
|
flag.StringVar(&FileCfg, "config", "config.ini", "Файл настроек")
|
||||||
flag.BoolVar(&CreateFileCfg, "create-config", false, "Создать файл настроек")
|
flag.BoolVar(&CreateFileCfg, "create-config", false, "Создать файл настроек")
|
||||||
flag.BoolVar(&Debug, "debug", false, "Выводить данные в консоль")
|
flag.BoolVar(&Debug, "debug", false, "Выводить отладочную информацию")
|
||||||
flag.StringVar(&DirIn, "dir-in", "in", "Каталог для исходных файлов (DIR_IN)")
|
flag.StringVar(&DirIn, "dir-in", "in", "Каталог для исходных файлов (DIR_IN)")
|
||||||
flag.StringVar(&DirOut, "dir-out", "out", "Каталог для обработанных файлов (DIR_OUT)")
|
flag.StringVar(&DirOut, "dir-out", "out", "Каталог для обработанных файлов (DIR_OUT)")
|
||||||
flag.StringVar(&DirTemp, "dir-temp", "tmp", "Каталог для временных файлов (TEMP)")
|
flag.StringVar(&DirTemp, "dir-temp", "tmp", "Каталог для временных файлов (TEMP)")
|
||||||
flag.StringVar(&DirLog, "dir-log", "log", "Каталог для лога работы (DIR_LOG)")
|
flag.StringVar(&DirLog, "dir-worklog", "log", "Каталог для лога работы (DIR_LOG)")
|
||||||
flag.StringVar(&DictFile, "dict-file", "1Cv8.lgf", "Файл со словарём (DICT_FILE)")
|
flag.StringVar(&DictFile, "dict-file", "1Cv8.lgf", "Файл со словарём (DICT_FILE)")
|
||||||
flag.BoolVar(&SendToEs, "es-send", false, "Отправлять данные в ElasticSearch")
|
flag.BoolVar(&SendToEs, "es-send", false, "Отправлять данные в ElasticSearch")
|
||||||
flag.StringVar(&EsUrl, "es-url", "", "Адрес узла Elastic Search (ELASTICSEARCH_URL)")
|
flag.StringVar(&EsUrl, "es-url", "", "Адрес узла Elastic Search (ELASTICSEARCH_URL)")
|
||||||
|
@ -1323,7 +1349,8 @@ func main() {
|
||||||
flag.StringVar(&ObjectTypes, "object-types", "1,2,3,4,5,6,7,8", "Список типов объектов словаря для выборки, разделённый запятой (OBJECT_TYPES)")
|
flag.StringVar(&ObjectTypes, "object-types", "1,2,3,4,5,6,7,8", "Список типов объектов словаря для выборки, разделённый запятой (OBJECT_TYPES)")
|
||||||
flag.StringVar(&TimeZoneOffset, "tz-offset", "+03:00", "Сдвиг по времени от UTC")
|
flag.StringVar(&TimeZoneOffset, "tz-offset", "+03:00", "Сдвиг по времени от UTC")
|
||||||
flag.StringVar(&Duration, "tail-sleep", "5ms", "Задержка чтения входного файла. Разрешены обозначения 'ns', 'us' ('µs'), 'ms', 's', 'm','h')")
|
flag.StringVar(&Duration, "tail-sleep", "5ms", "Задержка чтения входного файла. Разрешены обозначения 'ns', 'us' ('µs'), 'ms', 's', 'm','h')")
|
||||||
// flag.StringVar(&ExcludeEvent, "exclude-event", "", "Список событий исключенных из выдачи разделенных ';'")
|
flag.StringVar(&InFile, "file", "", "Имя файла для обработки. Если требуется обработать один файл")
|
||||||
|
flag.StringVar(&WorkLogOut, "worklog-out", "file", "Направление вывода журнала работы программы (console, file)")
|
||||||
|
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
|
@ -1407,17 +1434,26 @@ func main() {
|
||||||
|
|
||||||
createWorkDir()
|
createWorkDir()
|
||||||
|
|
||||||
// Установка и открытие лога для порграммы
|
// Определим куда выводим лог работы
|
||||||
fLog, err := os.OpenFile(filepath.Join(DirLog, "1c-log-processor.log"), os.O_RDWR | os.O_CREATE | os.O_APPEND, 0666)
|
switch WorkLogOut {
|
||||||
if err != nil {
|
case "file":
|
||||||
fmt.Printf("error opening log file: %v", err)
|
// Установка и открытие лога для программы
|
||||||
}
|
fLog, err := os.OpenFile(filepath.Join(DirLog, "1c-log-processor.log"), os.O_RDWR | os.O_CREATE | os.O_APPEND, 0666)
|
||||||
defer fLog.Close()
|
if err != nil {
|
||||||
if Debug {
|
fmt.Printf("error opening log file: %v", err)
|
||||||
log.SetOutput(os.Stdout)
|
}
|
||||||
} else {
|
defer fLog.Close()
|
||||||
log.SetOutput(fLog)
|
log.SetOutput(fLog)
|
||||||
|
case "console":
|
||||||
|
log.SetOutput(os.Stdout)
|
||||||
}
|
}
|
||||||
|
// if Debug {
|
||||||
|
// log.SetOutput(os.Stdout)
|
||||||
|
// } else {
|
||||||
|
// log.SetOutput(fLog)
|
||||||
|
// }
|
||||||
|
// log.SetOutput(fLog)
|
||||||
|
|
||||||
// readDictFile(dictFile)
|
// readDictFile(dictFile)
|
||||||
DictObjects = readDictFile(DictFile)
|
DictObjects = readDictFile(DictFile)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue