I have some unifi devices myself and use the following rules to get a “valid” hostname:
rule "unifi split source"
when
has_field("source") AND
contains(to_string($message.source), "U7LT") OR
contains(to_string($message.source), "US8P60") OR
contains(to_string($message.source), "US16P150")
// didn't yet find a better way doing this
then
// clean up source and get device information out of the fucking string that is provided as source
// needs the following defined grok pattern in the system
// UNIFIYSOURCES = ("%{WORD:device_type},%{WORD:device_mac},%{NOTSPACE:device_version}")
let source_field = to_string($message.source);
let source_split = grok(pattern: "%{UNIFIYSOURCES}", value: source_field, only_named_captures: true);
set_fields(source_split);
end
That helps me to have all three available information in a single field (and I can spot easy when a software update is not yet rolled out complete).
After that you have two options, depending of the number of devices you have. Create a second stage in the pipeline and write one rule for each device like
rule "unifi set hostname (802aa893d851)"
when
has_field("device_mac") AND contains(to_string($message.device_mac), "802aa893d851")
then
set_field("source", "ap-office.lan");
end
Or create a lookup table that contains the device MACs and hostnames and use that in one rule to fit all devices.
rule "unifi set hostname from LUT"
when
// use as much fields as possible to
// remove false lookups if device_mac might be present
// on other messages
has_field("device_mac") AND
has_field("device_type")
then
// get hostname based on MAC for unifi devices
let update_source = lookup_value("unifi-hostname-lookuptable", $message.device_mac);
set_field("source", update_source);
end