thats my solution:
[{"id":"dc71ac07a95659c3","type":"exec","z":"7667425061cb9763","command":"tail -n 100 /var/log/fail2ban.log | grep \"Ban\"","addpay":"","append":"","useSpawn":"false","timer":"2","winHide":false,"oldrc":false,"name":"fail2ban","x":320,"y":420,"wires":[["11e68e569fe20be4"],[],[]]},{"id":"285f2b0fa73c5141","type":"inject","z":"7667425061cb9763","name":"jede Minute","props":[{"p":"payload"}],"repeat":"60","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"true","payloadType":"bool","x":110,"y":420,"wires":[["dc71ac07a95659c3","c29ab3f614c5082b"]]},{"id":"11e68e569fe20be4","type":"split","z":"7667425061cb9763","name":"Log aufteilen","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","property":"payload","x":550,"y":400,"wires":[["804b2ce39b17f98a"]]},{"id":"804b2ce39b17f98a","type":"function","z":"7667425061cb9763","name":"Fail2Ban","func":"let logEntry = msg.payload;\nif (!logEntry.trim()) {\n return null;\n}\nlet regex = /(\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2},\\d{3})\\s+fail2ban.actions\\s+\\[\\d+\\]:\\s+NOTICE\\s+\\[([^\\]]+)\\]\\s+Ban\\s+([a-fA-F0-9:.]+)/;\nlet match = regex.exec(logEntry);\nif (match) {\n let timestamp = match[1];\n let service = match[2];\n let ipAddress = match[3];\n let date = new Date(timestamp.replace(',', '.'));\n let timeInMillis = date.getTime();\n let result = {\n IP: ipAddress,\n Dienst: service,\n time: timeInMillis\n };\n msg.payload = result;\n return msg;\n} \nelse {\n node.warn(\"Kein passender Log-Eintrag gefunden\");\n return null;\n}","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":540,"y":440,"wires":[["e3eabf06f5759e16"]]},{"id":"e3eabf06f5759e16","type":"influxdb out","z":"7667425061cb9763","influxdb":"65f9e27871c73f7e","name":"Fail2Ban","measurement":"Fail2Ban","precision":"ms","retentionPolicy":"","database":"database","precisionV18FluxV20":"ms","retentionPolicyV18Flux":"","org":"organisation","bucket":"bucket","x":760,"y":440,"wires":[]},{"id":"b732a0ce799cc393","type":"influxdb in","z":"7667425061cb9763","influxdb":"65f9e27871c73f7e","name":"Fail2Ban","query":"select * from \"Fail2Ban\" order by time desc Limit 30","rawOutput":false,"precision":"","retentionPolicy":"","org":"organisation","x":320,"y":480,"wires":[["9318c96dd873b946"]]},{"id":"602fae0cf5cf60fe","type":"ui_template","z":"7667425061cb9763","group":"0174de37aa15dc39","name":"Fail2Ban","order":6,"width":0,"height":0,"format":"<style>\n tr:hover {\n background-color: #f9f9f9;\n }\n td,\n th {\n font-size: 14px;\n border: 1px solid #ddd;\n }\n th {\n background-color: #f2f2f2;\n text-align: center;\n }\n\n td {\n text-align: left;\n }\n</style>\n<div>\n <table class=\"table table-bordered\" style=\"width: 100%; border-collapse: collapse;\">\n <thead>\n <tr>\n <th>Zeitpunkt</th>\n <th>IP Adresse</th>\n <th>Dienst</th>\n </tr>\n </thead>\n <tbody>\n <tr ng-repeat=\"entry in msg.payload\">\n <td>{{ entry.time }}</td>\n <td>{{ entry.IP }}</td>\n <td>{{ entry.Dienst }}</td>\n </tr>\n </tbody>\n </table>\n</div>","storeOutMessages":true,"fwdInMessages":false,"resendOnRefresh":true,"templateScope":"local","className":"","x":760,"y":480,"wires":[[]]},{"id":"c29ab3f614c5082b","type":"delay","z":"7667425061cb9763","name":"1s","pauseType":"delay","timeout":"1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":130,"y":480,"wires":[["b732a0ce799cc393"]]},{"id":"9318c96dd873b946","type":"function","z":"7667425061cb9763","name":"InfluxDB","func":"let data = msg.payload;\nif (Array.isArray(data)) {\n msg.payload = data.map(entry => {\n let date = new Date(entry.time);\n let weekday = date.toLocaleDateString('de-DE', { weekday: 'short' });\n let day = date.toLocaleDateString('de-DE', { day: '2-digit' });\n let month = date.toLocaleDateString('de-DE', { month: '2-digit' });\n let year = date.toLocaleDateString('de-DE', { year: 'numeric' });\n let time = date.toLocaleTimeString('de-DE', { hour: '2-digit', minute: '2-digit', second: '2-digit' });\n let formattedDate = `${weekday}, ${day}.${month}.${year} - ${time} Uhr`;\n return {\n time: formattedDate,\n IP: entry.IP,\n Dienst: entry.Dienst\n };\n });\n return msg;\n}\nelse {\n node.error(\"Die Daten sind im falschen Format\");\n return null;\n}","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":540,"y":480,"wires":[["602fae0cf5cf60fe"]]},{"id":"65f9e27871c73f7e","type":"influxdb","hostname":"192.168.168.5","port":8086,"protocol":"http","database":"db","name":"InfluxDB","usetls":false,"tls":"","influxdbVersion":"1.x","url":"http://localhost:8086","timeout":10,"rejectUnauthorized":true},{"id":"0174de37aa15dc39","type":"ui_group","name":"Fail2Ban","tab":"2353ff8665d46bde","order":1,"disp":true,"width":"10","collapse":false,"className":""},{"id":"2353ff8665d46bde","type":"ui_tab","name":"Fail2Ban","icon":"pan_tool","order":2,"disabled":false,"hidden":false}]
Grafana could also use it: