All Projects → sirkon → Ldetool

sirkon / Ldetool

Licence: mit
Code generator for fast log file parsers

Programming Languages

go
31211 projects - #10 most used programming language

Projects that are alternatives of or similar to Ldetool

allot
Parse placeholder and wildcard text commands
Stars: ✭ 51 (-81.32%)
Mutual labels:  parsing
CalPack
Packets in Python Simplified
Stars: ✭ 19 (-93.04%)
Mutual labels:  parsing
Docker Spark Cluster
A simple spark standalone cluster for your testing environment purposses
Stars: ✭ 261 (-4.4%)
Mutual labels:  bigdata
parse-md
Parse Markdown file's metadata from its content
Stars: ✭ 15 (-94.51%)
Mutual labels:  parsing
Compositional-Generalization-in-Natural-Language-Processing
Compositional Generalization in Natual Language Processing. A roadmap.
Stars: ✭ 26 (-90.48%)
Mutual labels:  parsing
DetEdit
A graphical user interface for annotating and editing events detected in long-term acoustic monitoring data
Stars: ✭ 20 (-92.67%)
Mutual labels:  bigdata
php.json
A library for simplifying JSON linting and validation.
Stars: ✭ 59 (-78.39%)
Mutual labels:  parsing
Nearley
📜🔜🌲 Simple, fast, powerful parser toolkit for JavaScript.
Stars: ✭ 3,089 (+1031.5%)
Mutual labels:  parsing
ofxgo
Golang library for querying and parsing OFX
Stars: ✭ 96 (-64.84%)
Mutual labels:  parsing
Stringsareevil
Reducing memory allocations from 7.5GB to 32KB
Stars: ✭ 260 (-4.76%)
Mutual labels:  parsing
python-hslog
Python module to parse Hearthstone Power.log files
Stars: ✭ 37 (-86.45%)
Mutual labels:  parsing
literator
📝 Generate literate-style markdown docs from your sources
Stars: ✭ 55 (-79.85%)
Mutual labels:  parsing
inmemantlr
ANTLR as a libray for JVM based languages
Stars: ✭ 87 (-68.13%)
Mutual labels:  parsing
rest-query-parser
Query Parser for REST
Stars: ✭ 29 (-89.38%)
Mutual labels:  parsing
Angourimath
Open-source symbolic algebra library for C# and F#. One of the most powerful in .NET
Stars: ✭ 266 (-2.56%)
Mutual labels:  parsing
tools-python
A Python library to parse, validate and create SPDX documents.
Stars: ✭ 65 (-76.19%)
Mutual labels:  parsing
jigsaw-seed
这是组件库 Jigsaw-七巧板(https://github.com/rdkmaster/jigsaw) 的种子工程,建议所有新增的app都以这个工程作为种子开始构建。
Stars: ✭ 17 (-93.77%)
Mutual labels:  bigdata
Creek
Ruby library for parsing large Excel files.
Stars: ✭ 270 (-1.1%)
Mutual labels:  parsing
Nlpython
This repository contains the code related to Natural Language Processing using python scripting language. All the codes are related to my book entitled "Python Natural Language Processing"
Stars: ✭ 265 (-2.93%)
Mutual labels:  parsing
Big Data Rosetta Code
Code snippets for solving common big data problems in various platforms. Inspired by Rosetta Code
Stars: ✭ 254 (-6.96%)
Mutual labels:  bigdata

ldetool means line data extraction tool

ldetool is a command line utility to generate Go code for fast log files parsing.

GO111MODULE=on go get github.com/sirkon/ldetool
  1. Contributors
  2. Rationale
  3. Typical operations and formal set of rules
  4. Performance comparison against regexp and Ragel
  5. Usage examples

How it works.

  1. First write extraction script, we usually name it <something>.lde
  2. Generate go code with ldetool <something.lde> --package main. Of course you can use your own package name, not only main
  3. Use it via the generated extraction method Parse(line []byte).

It turned out we like using it even for non-performant tasks, where we are dealing with strings, not slices of bytes and it would be handy to use it for strings as well without manual type casting. There's an option to generate code that use string, just put an option --go-string

CLI utility options
  1. --go-string generates code that uses string everywhere instead of []byte. You better not to use it for log processing as it may lead to excessive memory allocations.
  2. --yaml-dict or --json-dict sets translation rules for names. For instance, if we have YAML file with
    http: HTTP
    
    and feed this file to the ldetool then every name (of field or rule itself) like GetHttpHandle or get_http_handle will be translated into GetHTTPHandle
  3. --package <pkg name> name of the package to use in generated code. If a directory of *.lde file has other Go files package name will automatically setup with these files' package name.
  4. --big-endian or --little-endian sets the target architecture to be either big or little endian. This enables prefix check optimization

Example

Take a look at these two lines

[2017-09-02T22:48:13] FETCH first[1] format[JSON] hidden[0] userAgent[Android App v1.0] rnd[21341975] country[MA]
[2017-09-02T22:48:14] FETCH first[0] format[JSON] userAgent[Android App v1.0] rnd[10000000] country[LC]

We likely need a time, value of parameter first, format, hidden, userAgent and country. We obviously don't need rnd

Extraction script syntax

See more details on extraction rules

# filename: line.lde
Line =                                   # Name of the extraction object' type
  ^'[' Time(string) ']'                  # The line must start with [, then take everything as a struct field Time string right to ']' character
  ^" FETCH "                             # Current rest must starts with " FETCH " string
  ^"first[" First(uint8) ']'[1]          # The rest must starts with "first[" characters, then take the rest until ']' as uint8. It is
                                         # known First is the single character, thus the [1] index.
                                         # under the name of First
  ^" format[" Format(string) ~']'        # Take format id. Format is a short word: XML, JSON, BIN. ~ before lookup oobject suggests
                                         # generator to use for loop scan rather than IndexByte, which is although fast
                                         # has call overhead as it cannot be inlined by Go compiler.
  ?Hidden (^" hidden[" Value(uint8) ']') # Optionally look for " hidden[\d+]"
  ^" user_agent[" UserAgent(string) ']'  # User agent data
  _ "country[" Country(string)  ']'      # Look for the piece starting with country[
;
Code generation

The recommended way is to put something like //go:generate ldetool --package main Line.lde in generate.go of a package and then generate a code with

go generate <project path>

It will be written into line_lde.go file in the same directory. It will look like this

Now, we have

  1. Data extractor type
    // Line autogenerated parser
    type Line struct {
        Rest   []byte
        Time   []byte
        First  uint8
        Format []byte
        Hidden struct {
            Valid bool
            Value uint8
        }
        UserAgent []byte
        Country   []byte
    }
    
  2. Parse method
    // Extract autogenerated method of Line
    func (p *Line) Extract(line []byte) (bool, error) {
       
    }
    
    Take a look at return data. First bool signals if the data was successfully matched and error that is not nil signals if there were any error. String to numeric failures are always treated as errors, you can put ! into extraction script and all mismatches after the sign will be treated as errors
  3. Helper to access optional Hidden area returning default Go value if the the area was not matched
    // GetHiddenValue retrieves optional value for HiddenValue.Name
    func (p *Line) GetHiddenValue() (res uint8) {
        if !p.Hidden.Valid {
            return
        }
        return p.Hidden.Value
    }
    
Generated code usage

It is easy: put

l := &Line{}

before and then feed Extract method with lines:

scanner := bufio.NewScanner(reader)
for scanner.Scan() {
    ok, err := l.Extract(scanner.Bytes())
    if !ok {
        if err != nil {
            return err
        }
        continue
    }
    
    l.Format
    l.Time
    l.GetHiddenValue()
    
}

custom types

Special thanks to Matt Hook (github.com/hookenz) who proposed this feature

It is possible to use custom types in generated structure. You should declare them first via

type pkg.Type from "pkgpath";

for external types and

type typeName;

for local types before all rules definitions and you can use them as field types. The parsing to be done via

p.unmarshal<FieldName>([]byte) (Type, error)

function.

Example:

type time.Time from "time";
type net.IP from "net";

Custom = Time(time.Time) ' ' ?Addr(^"addr: " IP(ip.IP) ' ');

Now, two parsing functions will be needed to parse this (they are to be written manually):

func (p *Custom) unmarshalTime(s string) (time.Time, error) {  }

func (p *Custom) unmarshalAddrIP(s string) (net.IP, error) {  }
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].