Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
dcdb
dcdb
Commits
5af0eb23
Commit
5af0eb23
authored
Oct 30, 2020
by
Michael Ott
Browse files
Add tagFilter to InfluxDB REST API for filtering measurements by tags
parent
b96bd99e
Changes
3
Hide whitespace changes
Inline
Side-by-side
collectagent/CARestAPI.cpp
View file @
5af0eb23
...
@@ -146,7 +146,9 @@ void CARestAPI::POST_write(endpointArgs) {
...
@@ -146,7 +146,9 @@ void CARestAPI::POST_write(endpointArgs) {
std
::
istringstream
body
(
req
.
body
());
std
::
istringstream
body
(
req
.
body
());
std
::
string
line
;
std
::
string
line
;
while
(
std
::
getline
(
body
,
line
))
{
while
(
std
::
getline
(
body
,
line
))
{
// Regex to split line into measurement, tags, fields, timestamp
boost
::
regex
r1
(
"^([^,]*)(,[^ ]*)? ([^ ]*)( .*)?$"
,
boost
::
regex
::
extended
);
boost
::
regex
r1
(
"^([^,]*)(,[^ ]*)? ([^ ]*)( .*)?$"
,
boost
::
regex
::
extended
);
// Regex to split comma-separated tags and fields into individual entries
boost
::
regex
r2
(
",?([^,=]*)=([^,]*)"
,
boost
::
regex
::
extended
);
boost
::
regex
r2
(
",?([^,=]*)=([^,]*)"
,
boost
::
regex
::
extended
);
boost
::
smatch
m1
,
m2
;
boost
::
smatch
m1
,
m2
;
...
@@ -154,20 +156,34 @@ void CARestAPI::POST_write(endpointArgs) {
...
@@ -154,20 +156,34 @@ void CARestAPI::POST_write(endpointArgs) {
std
::
string
measurement
=
m1
[
1
].
str
();
std
::
string
measurement
=
m1
[
1
].
str
();
auto
m
=
_influxMap
.
find
(
measurement
);
auto
m
=
_influxMap
.
find
(
measurement
);
if
(
m
!=
_influxMap
.
end
())
{
if
(
m
!=
_influxMap
.
end
())
{
influx_t
influx
=
m
->
second
;
// Parse tags into a map
std
::
map
<
std
::
string
,
std
::
string
>
tags
;
std
::
map
<
std
::
string
,
std
::
string
>
tags
;
std
::
string
tag
Str
=
m1
[
2
].
str
();
std
::
string
tag
List
=
m1
[
2
].
str
();
while
(
boost
::
regex_search
(
tag
Str
,
m2
,
r2
))
{
while
(
boost
::
regex_search
(
tag
List
,
m2
,
r2
))
{
tags
[
m2
[
1
].
str
()]
=
m2
[
2
].
str
();
tags
[
m2
[
1
].
str
()]
=
m2
[
2
].
str
();
tag
Str
=
m2
.
suffix
().
str
();
tag
List
=
m2
.
suffix
().
str
();
}
}
auto
t
=
tags
.
find
(
m
->
second
.
tag
);
auto
t
=
tags
.
find
(
influx
.
tag
);
if
(
t
!=
tags
.
end
())
{
if
(
t
!=
tags
.
end
())
{
std
::
string
tagName
=
t
->
second
;
// Perform pattern filter or substitution via regex on tag
if
(
!
influx
.
tagRegex
.
empty
())
{
std
::
string
input
(
tagName
);
tagName
=
""
;
boost
::
regex_replace
(
std
::
back_inserter
(
tagName
),
input
.
begin
(),
input
.
end
(),
influx
.
tagRegex
,
influx
.
tagSubstitution
.
c_str
(),
boost
::
regex_constants
::
format_sed
|
boost
::
regex_constants
::
format_no_copy
);
if
(
tagName
.
size
()
==
0
)
{
// There was no match
break
;
}
}
std
::
map
<
std
::
string
,
std
::
string
>
fields
;
std
::
map
<
std
::
string
,
std
::
string
>
fields
;
std
::
string
field
Str
=
m1
[
3
].
str
();
std
::
string
field
List
=
m1
[
3
].
str
();
while
(
boost
::
regex_search
(
field
Str
,
m2
,
r2
))
{
while
(
boost
::
regex_search
(
field
List
,
m2
,
r2
))
{
fields
[
m2
[
1
].
str
()]
=
m2
[
2
].
str
();
fields
[
m2
[
1
].
str
()]
=
m2
[
2
].
str
();
field
Str
=
m2
.
suffix
().
str
();
field
List
=
m2
.
suffix
().
str
();
}
}
DCDB
::
TimeStamp
ts
;
DCDB
::
TimeStamp
ts
;
...
@@ -176,12 +192,13 @@ void CARestAPI::POST_write(endpointArgs) {
...
@@ -176,12 +192,13 @@ void CARestAPI::POST_write(endpointArgs) {
}
catch
(...)
{
}
catch
(...)
{
}
}
for
(
auto
&
f
:
m
->
second
.
fields
)
{
for
(
auto
&
f
:
fields
)
{
if
(
fields
.
find
(
f
)
!=
fields
.
end
())
{
// If no fields were defined, we take any field
std
::
string
mqttTopic
=
m
->
second
.
mqttPrefix
+
"/"
+
t
->
second
+
"/"
+
f
;
if
(
influx
.
fields
.
empty
()
||
(
influx
.
fields
.
find
(
f
.
first
)
!=
influx
.
fields
.
end
()))
{
std
::
string
mqttTopic
=
m
->
second
.
mqttPrefix
+
"/"
+
tagName
+
"/"
+
f
.
first
;
uint64_t
value
=
0
;
uint64_t
value
=
0
;
try
{
try
{
value
=
stoull
(
f
ields
[
f
]
);
value
=
stoull
(
f
.
second
);
}
catch
(...)
{
}
catch
(...)
{
break
;
break
;
}
}
...
@@ -191,11 +208,14 @@ void CARestAPI::POST_write(endpointArgs) {
...
@@ -191,11 +208,14 @@ void CARestAPI::POST_write(endpointArgs) {
_sensorCache
->
storeSensor
(
sid
,
ts
.
getRaw
(),
value
);
_sensorCache
->
storeSensor
(
sid
,
ts
.
getRaw
(),
value
);
_sensorDataStore
->
insert
(
&
sid
,
ts
.
getRaw
(),
value
,
0
);
//Fixme: TTL
_sensorDataStore
->
insert
(
&
sid
,
ts
.
getRaw
(),
value
,
0
);
//Fixme: TTL
}
}
#ifdef DEBUG
LOG
(
debug
)
<<
"influx insert: "
<<
mqttTopic
<<
" "
<<
ts
.
getRaw
()
<<
" "
<<
fields
[
f
];
LOG
(
debug
)
<<
"influx insert: "
<<
mqttTopic
<<
" "
<<
ts
.
getRaw
()
<<
" "
<<
value
;
#endif
}
}
}
}
}
}
}
else
{
LOG
(
debug
)
<<
"influx: unknown measurement "
<<
measurement
;
}
}
}
}
}
}
...
...
collectagent/configuration.cpp
View file @
5af0eb23
...
@@ -81,6 +81,20 @@ void Configuration::readAdditionalBlocks(boost::property_tree::iptree& cfg) {
...
@@ -81,6 +81,20 @@ void Configuration::readAdditionalBlocks(boost::property_tree::iptree& cfg) {
BOOST_FOREACH
(
boost
::
property_tree
::
iptree
::
value_type
&
m
,
global
.
second
)
{
BOOST_FOREACH
(
boost
::
property_tree
::
iptree
::
value_type
&
m
,
global
.
second
)
{
if
(
boost
::
iequals
(
m
.
first
,
"tag"
))
{
if
(
boost
::
iequals
(
m
.
first
,
"tag"
))
{
influx
.
tag
=
m
.
second
.
data
();
influx
.
tag
=
m
.
second
.
data
();
}
else
if
(
boost
::
iequals
(
m
.
first
,
"tagfilter"
))
{
//check if input has sed format of "s/.../.../" for substitution
boost
::
regex
checkSubstitute
(
"s([^
\\\\
]{1})([
\\
S|
\\
s]*)
\\
1([
\\
S|
\\
s]*)
\\
1"
);
boost
::
smatch
matchResults
;
if
(
regex_match
(
m
.
second
.
data
(),
matchResults
,
checkSubstitute
))
{
//input has substitute format
influx
.
tagRegex
=
boost
::
regex
(
matchResults
[
2
].
str
(),
boost
::
regex_constants
::
extended
);
influx
.
tagSubstitution
=
matchResults
[
3
].
str
();
}
else
{
//input is only a regex
influx
.
tagRegex
=
boost
::
regex
(
m
.
second
.
data
(),
boost
::
regex_constants
::
extended
);
influx
.
tagSubstitution
=
"&"
;
}
}
else
if
(
boost
::
iequals
(
m
.
first
,
"mqttprefix"
))
{
}
else
if
(
boost
::
iequals
(
m
.
first
,
"mqttprefix"
))
{
influx
.
mqttPrefix
=
m
.
second
.
data
();
influx
.
mqttPrefix
=
m
.
second
.
data
();
}
else
if
(
boost
::
iequals
(
m
.
first
,
"fields"
))
{
}
else
if
(
boost
::
iequals
(
m
.
first
,
"fields"
))
{
...
...
collectagent/configuration.h
View file @
5af0eb23
...
@@ -31,6 +31,8 @@
...
@@ -31,6 +31,8 @@
#include <string>
#include <string>
#include <unistd.h>
#include <unistd.h>
#include <boost/algorithm/string/trim.hpp>
#include <boost/algorithm/string/trim.hpp>
#include <boost/regex.hpp>
#include "logging.h"
#include "logging.h"
#include "globalconfiguration.h"
#include "globalconfiguration.h"
...
@@ -66,8 +68,10 @@ public:
...
@@ -66,8 +68,10 @@ public:
class
influx_t
{
class
influx_t
{
public:
public:
influx_t
()
{}
influx_t
()
{}
std
::
string
mqttPrefix
;
std
::
string
mqttPrefix
;
std
::
string
tag
;
std
::
string
tag
;
boost
::
regex
tagRegex
;
std
::
string
tagSubstitution
;
std
::
set
<
std
::
string
>
fields
;
std
::
set
<
std
::
string
>
fields
;
};
};
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment