| Stability | experimental |
|---|---|
| Portability | GHC |
| Safe Haskell | None |
| Language | Haskell2010 |
Database.InfluxDB
Contents
Description
- write :: Timestamp time => WriteParams -> Line time -> IO ()
- writeBatch :: (Timestamp time, Foldable f) => WriteParams -> f (Line time) -> IO ()
- writeByteString :: WriteParams -> ByteString -> IO ()
- data WriteParams
- writeParams :: Database -> WriteParams
- retentionPolicy :: Lens' WriteParams (Maybe Key)
- data Line time = Line !Measurement !(Map Key Key) !(Map Key LineField) !(Maybe time)
- measurement :: Lens' (Line time) Measurement
- tagSet :: Lens' (Line time) (Map Key Key)
- fieldSet :: Lens' (Line time) (Map Key LineField)
- timestamp :: Lens' (Line time) (Maybe time)
- data Field (n :: Nullability) where
- type LineField = Field NonNullable
- type QueryField = Field Nullable
- class Timestamp time where
- precisionScale :: Fractional a => Precision ty -> a
- precisionName :: Precision ty -> Text
- data Query
- query :: QueryResults a => QueryParams -> Query -> IO (Vector a)
- queryChunked :: QueryResults a => QueryParams -> Optional Int -> Query -> FoldM IO (Vector a) r -> IO r
- formatQuery :: Format Query r -> r
- (%) :: Format b c -> Format a b -> Format a c
- data QueryParams
- queryParams :: Database -> QueryParams
- authentication :: HasCredentials a => Lens' a (Maybe Credentials)
- class QueryResults a where
- parseResultsWith :: (Maybe Text -> HashMap Text Text -> Vector Text -> Array -> Parser a) -> Value -> Parser (Vector a)
- getField :: Monad m => Text -> Vector Text -> Vector Value -> m Value
- getTag :: Monad m => Text -> HashMap Text Value -> m Value
- parseUTCTime :: Precision ty -> Value -> Parser UTCTime
- parsePOSIXTime :: Precision ty -> Value -> Parser POSIXTime
- parseQueryField :: Value -> Parser QueryField
- manage :: QueryParams -> Query -> IO ()
- data Precision (ty :: RequestType) where
- Nanosecond :: Precision ty
- Microsecond :: Precision ty
- Millisecond :: Precision ty
- Second :: Precision ty
- Minute :: Precision ty
- Hour :: Precision ty
- RFC3339 :: Precision QueryRequest
- data Database
- formatDatabase :: Format Database r -> r
- data Measurement
- formatMeasurement :: Format Measurement r -> r
- data Key
- formatKey :: Format Key r -> r
- data Server
- defaultServer :: Server
- host :: Lens' Server Text
- port :: Lens' Server Int
- ssl :: Lens' Server Bool
- data Credentials
- credentials :: Text -> Text -> Credentials
- user :: Lens' Credentials Text
- password :: Lens' Credentials Text
- data InfluxException
- class HasServer a where
- class HasDatabase a where
- class HasPrecision (ty :: RequestType) a | a -> ty where
- class HasManager a where
Documentation
Getting started
This tutorial assumes the following language extensions and imports.
>>>:set -XOverloadedStrings>>>:set -XRecordWildCards>>>import Database.InfluxDB>>>import qualified Database.InfluxDB.Format as F>>>import Control.Lens>>>import qualified Data.Map as Map>>>import Data.Time>>>import qualified Data.Vector as V
The examples below roughly follows the README in the official Go client library.
Creating a database
This library assumes the lens
package in some APIs. Here we use ?~ to set the authentication
parameters of type Maybe .Credentials
Also note that in order to construct a Query, we use formatQuery with the
database formatter. There are many other formatters defined in
Database.InfluxDB.Format.
>>>let db = "square_holes">>>let bubba = credentials "bubba" "bumblebeetuna">>>let p = queryParams db & authentication ?~ bubba>>>manage p $ formatQuery ("DROP DATABASE "%F.database) db>>>manage p $ formatQuery ("CREATE DATABASE "%F.database) db
Writing data
write or writeBatch can be used to write data. In general writeBatch
should be used for efficiency when writing multiple data points.
>>>let wp = writeParams db & authentication ?~ bubba & precision .~ Second>>>let cpuUsage = "cpu_usage">>>:{writeBatch wp [ Line cpuUsage (Map.singleton "cpu" "cpu-total") (Map.fromList [ ("idle", FieldFloat 10.1) , ("system", FieldFloat 53.3) , ("user", FieldFloat 46.6) ]) (Just $ parseTimeOrError False defaultTimeLocale "%F %T%Q %Z" "2017-06-17 15:41:40.42659044 UTC") :: Line UTCTime ] :}
Note that the type signature of the timestamp is necessary. Otherwise it doesn't type check.
Querying data
First we define a placeholder data type called CPUUsage and a QueryResults
instance. getField, parseUTCTime and parseQueryField etc are avilable to
make JSON decoding easier.
>>>:{data CPUUsage = CPUUsage { time :: UTCTime , cpuIdle, cpuSystem, cpuUser :: Double } deriving Show instance QueryResults CPUUsage where parseResults prec = parseResultsWithDecoder strictDecoder $ \_ _ columns fields -> do time <- getField "time" columns fields >>= parseUTCTime prec FieldFloat cpuIdle <- getField "idle" columns fields >>= parseQueryField FieldFloat cpuSystem <- getField "system" columns fields >>= parseQueryField FieldFloat cpuUser <- getField "user" columns fields >>= parseQueryField return CPUUsage {..} :}
>>>query p $ formatQuery ("SELECT * FROM "%F.measurement) cpuUsage :: IO (V.Vector CPUUsage)[CPUUsage {time = 2017-06-17 15:41:40 UTC, cpuIdle = 10.1, cpuSystem = 53.3, cpuUser = 46.6}]
Note that the type signature on query here is also necessary to type check.
Writing data
InfluxDB has two ways to write data into it, via HTTP and UDP. This module only exports functions for the HTTP API. For UDP, you can use a qualified import:
import qualified Database.InfluxDB.Write.UDP as UDP
write :: Timestamp time => WriteParams -> Line time -> IO () #
Write a Line.
>>>let p = writeParams "test-db">>>write p $ Line "room_temp" Map.empty (Map.fromList [("temp", FieldFloat 25.0)]) (Nothing :: Maybe UTCTime)
writeBatch :: (Timestamp time, Foldable f) => WriteParams -> f (Line time) -> IO () #
Write multiple Lines in a batch.
This is more efficient than calling write multiple times.
>>>let p = writeParams "test-db">>>:{writeBatch p [ Line "temp" (Map.singleton "city" "tokyo") (Map.fromList [("temp", FieldFloat 25.0)]) (Nothing :: Maybe UTCTime) , Line "temp" (Map.singleton "city" "osaka") (Map.fromList [("temp", FieldFloat 25.2)]) (Nothing :: Maybe UTCTime) ] :}
writeByteString :: WriteParams -> ByteString -> IO () #
Write a raw ByteString
Write parameters
data WriteParams #
The full set of parameters for the HTTP writer.
Instances
| HasCredentials WriteParams # | Authentication info for the write
|
| HasManager WriteParams # |
|
| HasDatabase WriteParams # |
|
| HasServer WriteParams # |
|
| HasPrecision WriteRequest WriteParams # |
|
writeParams :: Database -> WriteParams #
Smart constructor for WriteParams
Default parameters:
retentionPolicy :: Lens' WriteParams (Maybe Key) #
Target retention policy for the write.
InfluxDB writes to the default retention policy if this parameter is set
to Nothing.
>>>let p = writeParams "foo" & retentionPolicy .~ Just "two_hours">>>p ^. retentionPolicyJust "two_hours"
The Line protocol
Placeholder for the Line Protocol
See https://docs.influxdata.com/influxdb/v1.2/write_protocols/line_protocol_tutorial/ for the concrete syntax.
measurement :: Lens' (Line time) Measurement #
Name of the measurement that you want to write your data to.
tagSet :: Lens' (Line time) (Map Key Key) #
Tag(s) that you want to include with your data point. Tags are optional in
the Line Protocol, so you can set it empty.
fieldSet :: Lens' (Line time) (Map Key LineField) #
Field(s) for your data point. Every data point requires at least one field
in the Line Protocol, so it shouldn't be empty.
timestamp :: Lens' (Line time) (Maybe time) #
Timestamp for your data point. You can put whatever type of timestamp that
is an instance of the Timestamp class.
data Field (n :: Nullability) where #
type LineField = Field NonNullable #
Field type for the line protocol. The line protocol doesn't accept null values.
type QueryField = Field Nullable #
Field type for queries. Queries can contain null values.
A Timestamp is something that can be converted to a valid
InfluxDB timestamp, which is represented as a 64-bit integer.
Methods
roundTo :: Precision WriteRequest -> time -> Int64 #
Round a time to the given precision and scale it to nanoseconds
scaleTo :: Precision WriteRequest -> time -> Int64 #
Scale a time to the given precision
precisionScale :: Fractional a => Precision ty -> a #
Scale of the type precision.
>>>precisionScale RFC33391.0e-9>>>precisionScale Microsecond1.0e-6
precisionName :: Precision ty -> Text #
Name of the time precision.
>>>precisionName Nanosecond"n"
Querying data
query and queryChunked can be used to query data. If your dataset fits your
memory, query is easier to use. If it doesn't, use queryChunked to stream
data.
An InfluxDB query.
A spec of the format is available at https://docs.influxdata.com/influxdb/v1.2/query_language/spec/.
A Query can be constructed using either
- the
IsStringinstance with-XOverloadedStrings - or
formatQuery.
>>>:set -XOverloadedStrings>>>"SELECT * FROM series" :: Query"SELECT * FROM series">>>import qualified Database.InfluxDB.Format as F>>>formatQuery ("SELECT * FROM "%F.key) "series""SELECT * FROM \"series\""
NOTE: Currently this library doesn't support type-safe query construction.
query :: QueryResults a => QueryParams -> Query -> IO (Vector a) #
Query data from InfluxDB.
It may throw InfluxException.
Arguments
| :: QueryResults a | |
| => QueryParams | |
| -> Optional Int | Chunk size By |
| -> Query | |
| -> FoldM IO (Vector a) r | |
| -> IO r |
Same as query but it instructs InfluxDB to stream chunked responses
rather than returning a huge JSON object. This can be lot more efficient than
query if the result is huge.
It may throw InfluxException.
Query construction
There are various utility functions available in Database.InfluxDB.Format. This module is designed to be imported as qualified:
import Database.InfluxDB import qualified Database.InfluxDB.Format as F
formatQuery :: Format Query r -> r #
Format a Query.
>>>formatQuery "SELECT * FROM series""SELECT * FROM series">>>formatQuery ("SELECT * FROM "%key) "series""SELECT * FROM \"series\""
Query parameters
data QueryParams #
The full set of parameters for the query API
Instances
| HasCredentials QueryParams # | Authentication info for the query
|
| HasManager QueryParams # |
|
| HasDatabase QueryParams # |
|
| HasServer QueryParams # |
|
| HasPrecision QueryRequest QueryParams # | Returning JSON responses contain timestamps in the specified precision/format.
|
queryParams :: Database -> QueryParams #
Smart constructor for QueryParams
Default parameters:
authentication :: HasCredentials a => Lens' a (Maybe Credentials) #
User name and password to be used when sending requests to InfluxDB.
Parsing results
class QueryResults a where #
Types that can be converted from an JSON object returned by InfluxDB.
For example the h2o_feet series in
the official document
can be encoded as follows:
>>>:{data H2OFeet = H2OFeet { time :: UTCTime , levelDesc :: T.Text , location :: T.Text , waterLevel :: Double } instance QueryResults H2OFeet where parseResults prec = parseResultsWith $ \_ _ columns fields -> do time <- getField "time" columns fields >>= parseUTCTime prec String levelDesc <- getField "level_description" columns fields String location <- getField "location" columns fields FieldFloat waterLevel <- getField "water_level" columns fields >>= parseQueryField return H2OFeet {..} :}
Minimal complete definition
Methods
parseResults :: Precision QueryRequest -> Value -> Parser (Vector a) #
Parse a JSON object as an array of values of expected type.
Instances
| QueryResults Void # | |
| QueryResults ShowSeries # | |
| QueryResults ShowQuery # | |
| ((~) * a Value, (~) * b Value) => QueryResults (a, b) # | |
| ((~) * a Value, (~) * b Value, (~) * c Value) => QueryResults (a, b, c) # | |
| ((~) * a Value, (~) * b Value, (~) * c Value, (~) * d Value) => QueryResults (a, b, c, d) # | |
| ((~) * a Value, (~) * b Value, (~) * c Value, (~) * d Value, (~) * e Value) => QueryResults (a, b, c, d, e) # | |
| ((~) * a Value, (~) * b Value, (~) * c Value, (~) * d Value, (~) * e Value, (~) * f Value) => QueryResults (a, b, c, d, e, f) # | |
| ((~) * a Value, (~) * b Value, (~) * c Value, (~) * d Value, (~) * e Value, (~) * f Value, (~) * g Value) => QueryResults (a, b, c, d, e, f, g) # | |
| ((~) * a Value, (~) * b Value, (~) * c Value, (~) * d Value, (~) * e Value, (~) * f Value, (~) * g Value, (~) * h Value) => QueryResults (a, b, c, d, e, f, g, h) # | |
Arguments
| :: (Maybe Text -> HashMap Text Text -> Vector Text -> Array -> Parser a) | A parser that takes
to construct a value. |
| -> Value | |
| -> Parser (Vector a) |
A helper function to parse a JSON response in
parseResults.
Get a field value from a column name
Get a tag value from a tag name
parseUTCTime :: Precision ty -> Value -> Parser UTCTime #
Parse either a POSIX timestamp or RFC3339 formatted timestamp as UTCTime.
parsePOSIXTime :: Precision ty -> Value -> Parser POSIXTime #
Parse either a POSIX timestamp or RFC3339 formatted timestamp as
POSIXTime.
parseQueryField :: Value -> Parser QueryField #
Parse a QueryField.
Database management
manage :: QueryParams -> Query -> IO () #
Send a database management query to InfluxDB.
>>>let db = "manage-test">>>let p = queryParams db>>>manage p $ F.formatQuery ("CREATE DATABASE "%F.database) db
Common data types and classes
data Precision (ty :: RequestType) where #
Predefined set of time precision.
RFC3339 is only available for QueryRequests.
Constructors
| Nanosecond :: Precision ty | POSIX time in ns |
| Microsecond :: Precision ty | POSIX time in μs |
| Millisecond :: Precision ty | POSIX time in ms |
| Second :: Precision ty | POSIX time in s |
| Minute :: Precision ty | POSIX time in minutes |
| Hour :: Precision ty | POSIX time in hours |
| RFC3339 :: Precision QueryRequest | Nanosecond precision time in a human readable format, like
|
Database name.
formatDatabase can be used to construct a
Database.
formatDatabase :: Format Database r -> r #
Format a Database.
>>>formatDatabase "test-db""test-db"
data Measurement #
String name that is used for measurements.
formatMeasurement can be used to construct a
Measurement.
Instances
formatMeasurement :: Format Measurement r -> r #
Format a Measurement.
>>>formatMeasurement "test-series""test-series"
String type that is used for tag keys/values and field keys.
defaultServer :: Server #
Arguments
| :: Text | User name |
| -> Text | Password |
| -> Credentials |
user :: Lens' Credentials Text #
User name to access InfluxDB.
>>>let creds = credentials "john" "passw0rd">>>creds ^. user"john"
password :: Lens' Credentials Text #
Password to access InfluxDB
Exception
data InfluxException #
Exceptions used in this library.
In general, the library tries to convert exceptions from the dependent libraries to the following types of errors.
Constructors
| ServerError String | Server side error. You can expect to get a successful response once the issue is resolved on the server side. |
| ClientError String Request | Client side error. You need to fix your query to get a successful response. |
| UnexpectedResponse String ByteString | Received an unexpected response. The This can happen e.g. when the response from InfluxDB is incompatible with what this library expects due to an upstream format change etc. |
| HTTPException HttpException | HTTP communication error. Typical HTTP errors (4xx and 5xx) are covered by |
Instances
Minimal complete definition
Instances
| HasServer PingParams # |
|
| HasServer QueryParams # |
|
| HasServer WriteParams # |
|
class HasDatabase a where #
Minimal complete definition
Instances
| HasDatabase QueryParams # |
|
| HasDatabase ShowQuery # | > v <- query (queryParams "_internal") "SHOW QUERIES" :: IO (V.Vector ShowQuery) > v ^.. each.database ["_internal"] |
| HasDatabase WriteParams # |
|
class HasPrecision (ty :: RequestType) a | a -> ty where #
Minimal complete definition
Instances
| HasPrecision QueryRequest QueryParams # | Returning JSON responses contain timestamps in the specified precision/format.
|
| HasPrecision WriteRequest WriteParams # |
|
| HasPrecision WriteRequest WriteParams # | Timestamp precision. In the UDP API, all timestamps are sent in nanosecond but you can specify lower precision. The writer just rounds timestamps to the specified precision. |
class HasManager a where #
Minimal complete definition
Methods
manager :: Lens' a (Either ManagerSettings Manager) #
HTTP manager settings or a manager itself.
If it's set to ManagerSettings, the library will create a Manager from
the settings for you.
Instances
| HasManager PingParams # |
|
| HasManager QueryParams # |
|
| HasManager WriteParams # |
|