Logrange is written in Golang, so "native" go client can be used for accessing Logrange from programs written in Golang. To get Logrange use:
go get -u -v github.com/logrange/logrange
The public API can be found in github.com/logrange/lograne/api package. Only one implementation available for accessing Logrange could be found in github.com/logrange/lograne/api/rpc. Logrange uses its own RPC implementation which works over TCP or TLS transport. More widely used gRPC and HTTP based REST API implementations are in our plans as well.
To create the client just call rpc.NewClient()
:
import "github.com/logrange/logrange/api/rpc"
import "github.com/logrange/range/pkg/transport"
...
client, err := rpc.NewClient(transport.Config{
ListenAddr: "127.0.0.1:9966",
})
The client expects transport configuration, which is defined in github.com/logrange/range/pkg/transport package.
If TlsEnabled
is not true
then TLS will not be enabled, so only ListenAddr
is expected.
To write data into Logrange Write
function of the client should be used. For example:
...
// preparing records
recs := []*api.LogEvent{
{
Timestamp: time.Now().UnixNano(),
Message: "Hello Logrange, first message",
}, {
Timestamp: time.Now().UnixNano(),
Message: "Hello Logrange, second message",
},
}
// Ingesting the recs into the partition with one tag
// "partition=testWrite", and apply the fields values "custField=test"
// to all records from the recs
var wr api.WriteResult
err = client.Write(context.Background(), "partition=testWrite", "custField=test",
recs, &wr)
...
The Write
allows to persist data into Logrange. It expects tags for the partition where records should be written to. The write operation will be done to the partition which contans ALL and ONLY the tags provided. If there is no such partition, it will be created.
Fields (only one field custField=test
in the example above) will be applied to all LogEvents in the write operaion. The Write operation ignores individual records fields, but apply the same fields to all the records.
To read data from one or many parition, Query
function should be used:
...
var qr api.QueryResult
err = client.Query(context.Background(),
&api.QueryRequest{Query: "SELECT FROM partition=testWrite", Limit: 100},
&qr)
...
To form the query parameters the api.QueryRequest should be used. Only SELECT
statements are accepted in the Query()
. Fields from api.QueryRequest
like Limit
, Offset
, Pos
etc. will overwrite the parameters from the Query
field text, so they have to be provided explicitly (Limit
is set to 100 in the example above, if we don't do this, the result will be empty).
Result of the query execution is returned via parameter qr
, a pointer to the variable with type api.QueryResult. Among the resulting records, the result contains NextQueryRequest
field which could be used for accessing next portion of records followed by the result.
There is a helper function, which allows "to stream" records from Logrange, sending the records into a "hook" function. The "hook" function will receive a portion of the records from the stream and the new portion will be received as soon as the current one is handled. If the stream doesn't have records, it will wait for new ones. Use api.Select() for the functionality:
// The select below will read data from the partition with tag
// "partition=testWrite" until it is interrupted or a communication error happens
cnt := 0
err = api.Select(
context.Background(),
client,
&api.QueryRequest{Query: "SELECT FROM partition=testWrite", Limit: 100, WaitTimeout: 10},
true,
func(qr *api.QueryResult) {
for _, ev := range qr.Events {
ts := time.Unix(0, ev.Timestamp)
fmt.Println(cnt, ": ts=", ts, ", msg=", ev.Message)
cnt++
}
},
)
In the example above records will be read from the partition tagged by partition=testWrite
, by portions of 100 records in each. The received records just simply printed into standard output. If the end of the stream is reached, the Select
function will wait for new records and call the function again, as soon as the new data is available.
The read-write example demonstrates how the write and read operations described above work together.
The streaming records example shows how the records could be read in streaming mode.
To build the examples just type the following commands from the source directory of github.com/logrange/logrange
on your local machine:
go build -o read-write ./examples/read-write
go build -o streaming-read ./examples/streaming-read
Use the 2 executables read-write
and streaming-read
to see how it works. You need to have Logrange server unning in its default configuration for listening clients requests on 127.0.0.1:9966
.