93_Log2Syslog.pm 132 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293
  1. ##########################################################################################################################
  2. # $Id: 93_Log2Syslog.pm 17636 2018-10-28 16:49:17Z DS_Starter $
  3. ##########################################################################################################################
  4. # 93_Log2Syslog.pm
  5. #
  6. # (c) 2017-2018 by Heiko Maaz
  7. # e-mail: Heiko dot Maaz at t-online dot de
  8. #
  9. # This script is part of fhem.
  10. #
  11. # Fhem is free software: you can redistribute it and/or modify
  12. # it under the terms of the GNU General Public License as published by
  13. # the Free Software Foundation, either version 2 of the License, or
  14. # (at your option) any later version.
  15. #
  16. # Fhem is distributed in the hope that it will be useful,
  17. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. # GNU General Public License for more details.
  20. #
  21. # You should have received a copy of the GNU General Public License
  22. # along with fhem. If not, see <http://www.gnu.org/licenses/>.
  23. #
  24. # The module is based on idea and input from betateilchen 92_rsyslog.pm
  25. #
  26. # Implements the Syslog Protocol of RFC 5424 https://tools.ietf.org/html/rfc5424
  27. # and RFC 3164 https://tools.ietf.org/html/rfc3164 and
  28. # TLS Transport according to RFC5425 https://tools.ietf.org/pdf/rfc5425.pdf as well
  29. #
  30. ##########################################################################################################################
  31. package main;
  32. use strict;
  33. use warnings;
  34. use TcpServerUtils;
  35. use Scalar::Util qw(looks_like_number);
  36. use Encode qw(encode_utf8);
  37. eval "use IO::Socket::INET;1" or my $MissModulSocket = "IO::Socket::INET";
  38. eval "use Net::Domain qw(hostname hostfqdn hostdomain domainname);1" or my $MissModulNDom = "Net::Domain";
  39. # Versions History intern:
  40. our %Log2Syslog_vNotesIntern = (
  41. "5.3.1" => "21.10.2018 get of FQDN changed ",
  42. "5.3.0" => "16.10.2018 attribute sslCertPrefix added (Forum:#92030), module hints & release info order switched ",
  43. "5.2.1" => "08.10.2018 setpayload of BSD-format changed, commandref revised ",
  44. "5.2.0" => "02.10.2018 added direct help for attributes",
  45. "5.1.0" => "01.10.2018 new get <name> versionNotes command",
  46. "5.0.1" => "27.09.2018 Log2Syslog_closesock if write error:.* , delete readings code changed",
  47. "5.0.0" => "26.09.2018 TCP-Server in Collector-mode, HIPCACHE added, PROFILE as Internal, Parse_Err_No as reading,
  48. octetCount attribute, TCP-SSL-support, set 'reopen' command, code fixes",
  49. "4.8.5" => "20.08.2018 BSD/parseFn parsing changed, BSD setpayload changed, new variable \$IGNORE in parseFn",
  50. "4.8.4" => "15.08.2018 BSD parsing changed",
  51. "4.8.3" => "14.08.2018 BSD setpayload changed, BSD parsing changed, Internal MYFQDN",
  52. "4.8.2" => "13.08.2018 rename makeMsgEvent to makeEvent",
  53. "4.8.1" => "12.08.2018 IETF-Syslog without VERSION changed, Log verbose 1 to 2 changed in parsePayload",
  54. "4.8.0" => "12.08.2018 enhanced IETF Parser to match logs without version",
  55. "4.7.0" => "10.08.2018 Parser for TPLink",
  56. "4.6.1" => "10.08.2018 some perl warnings, changed IETF Parser",
  57. "4.6.0" => "08.08.2018 set sendTestMessage added, Attribute 'contDelimiter', 'respectSeverity'",
  58. "4.5.1" => "07.08.2018 BSD Regex changed, setpayload of BSD changed",
  59. "4.5.0" => "06.08.2018 Regex capture groups used in parsePayload to set variables, parsing of BSD changed,
  60. Attribute 'makeMsgEvent' added",
  61. "4.4.0" => "04.08.2018 Attribute 'outputFields' added",
  62. "4.3.0" => "03.08.2018 Attribute 'parseFn' added",
  63. "4.2.0" => "03.08.2018 evaluate sender peer ip-address/hostname, use it as reading in event generation",
  64. "4.1.0" => "02.08.2018 state event generation changed",
  65. "4.0.0" => "30.07.2018 server mode (Collector)",
  66. "3.2.1" => "04.05.2018 fix compatibility with newer IO::Socket::SSL on debian 9, attr ssldebug for
  67. debugging SSL messages",
  68. "3.2.0" => "22.11.2017 add NOTIFYDEV if possible",
  69. "3.1.0" => "28.08.2017 get-function added, commandref revised, \$readingFnAttributes deleted",
  70. "3.0.0" => "27.08.2017 change attr type to protocol, ready to check in",
  71. "2.6.0" => "26.08.2017 more than one Log2Syslog device can be created",
  72. "2.5.2" => "26.08.2018 fix in splitting timestamp, change Log2Syslog_trate using internaltimer with attr
  73. rateCalcRerun, function Log2Syslog_closesock",
  74. "2.5.1" => "24.08.2017 some fixes",
  75. "2.5.0" => "23.08.2017 TLS encryption available, new readings, \$readingFnAttributes",
  76. "2.4.1" => "21.08.2017 changes in sub Log2Syslog_charfilter, change PROCID to \$hash->{SEQNO}
  77. switch to non-blocking in subs event/Log2Syslog_fhemlog",
  78. "2.4.0" => "20.08.2017 new sub Log2Syslog_Log3slog for entries in local fhemlog only -> verbose support",
  79. "2.3.1" => "19.08.2017 commandref revised",
  80. "2.3.0" => "18.08.2017 new parameter 'ident' in DEF, sub setidex, Log2Syslog_charfilter",
  81. "2.2.0" => "17.08.2017 set BSD data length, set only acceptable characters (USASCII) in payload,
  82. commandref revised",
  83. "2.1.0" => "17.08.2017 sub Log2Syslog_opensock created",
  84. "2.0.0" => "16.08.2017 create syslog without SYS::SYSLOG",
  85. "1.1.1" => "13.08.2017 registrate Log2Syslog_fhemlog to %loginform in case of sending fhem-log
  86. attribute timeout, commandref revised",
  87. "1.1.0" => "26.07.2017 add regex search to sub Log2Syslog_fhemlog",
  88. "1.0.0" => "25.07.2017 initial version"
  89. );
  90. # Versions History extern:
  91. our %Log2Syslog_vNotesExtern = (
  92. "5.3.0" => "16.10.2018 attribute sslCertPrefix added to support multiple SSL-keys (Forum:#92030)",
  93. "5.2.1" => "08.10.2018 Send format of BSD changed. The TAG-field was changed to \"IDENT[PID]: \" ",
  94. "5.2.0" => "02.10.2018 direct help for attributes added",
  95. "5.1.0" => "29.09.2018 new get &lt;name&gt; versionNotes command ",
  96. "5.0.1" => "27.09.2018 automatic reconnect to syslog-server in case of write error ",
  97. "5.0.0" => "26.09.2018 <li>TCP Server mode is possible now for Collector devices<\li><li>the used parse-profile is shown as Internal<\li><li>Parse_Err_No counts faulty persings since start<\li><li>new octetCount attribute switches the syslog framing method (see also RFC6587 <a href=\"https://tools.ietf.org/html/rfc6587\">Transmission of Syslog Messages over TCP</a>)<\li><li>TCP SSL-support<\li><li>new set 'reopen' command to reconnect a broken connection<\li><li>some code fixes ",
  98. "4.8.5" => "20.08.2018 BSD/parseFn parse changed, BSD setpayload changed, new variable \$IGNORE in parseFn ",
  99. "4.8.4" => "15.08.2018 BSD parse changed again ",
  100. "4.8.3" => "14.08.2018 BSD setpayload changed, BSD parse changed, new Internal MYFQDN ",
  101. "4.8.2" => "13.08.2018 rename makeMsgEvent to makeEvent ",
  102. "4.8.1" => "12.08.2018 IETF-Syslog without VERSION changed, Log verbose 1 to 2 changed in parsePayload ",
  103. "4.8.0" => "12.08.2018 enhanced IETF Parser to match logs without version ",
  104. "4.7.0" => "10.08.2018 Parser for TPLink added ",
  105. "4.6.1" => "10.08.2018 fix some perl warnings, changed IETF Parser ",
  106. "4.6.0" => "08.08.2018 set sendTestMessage added, new attributes 'contDelimiter', 'respectSeverity' ",
  107. "4.5.1" => "07.08.2018 BSD Regex changed, setpayload of BSD changed ",
  108. "4.5.0" => "06.08.2018 parsing of BSD changed, attribute 'makeMsgEvent' added ",
  109. "4.4.0" => "04.08.2018 Attribute 'outputFields' added ",
  110. "4.3.0" => "03.08.2018 Attribute 'parseFn' added ",
  111. "4.2.0" => "03.08.2018 evaluate sender peer ip-address/hostname and use it as reading in event generation ",
  112. "4.1.0" => "02.08.2018 state event generation changed ",
  113. "4.0.0" => "30.07.2018 Server mode (Collector) implemented ",
  114. "3.2.1" => "04.05.2018 fix compatibility with newer IO::Socket::SSL on debian 9, attribute ssldebug for debugging SSL messages ",
  115. "3.2.0" => "22.11.2017 add NOTIFYDEV if possible ",
  116. "3.1.0" => "28.08.2017 get-function added, commandref revised ",
  117. "3.0.0" => "27.08.2017 change attr type to protocol, ready to first check in ",
  118. "2.6.0" => "26.08.2017 more than one Log2Syslog device can be created ",
  119. "2.5.2" => "26.08.2018 attribute rateCalcRerun ",
  120. "2.5.1" => "24.08.2017 some bugfixes ",
  121. "2.5.0" => "23.08.2017 TLS encryption available to Sender ",
  122. "2.4.1" => "21.08.2017 change PROCID to \$hash->{SEQNO}, switch to non-blocking in subs event/fhemlog ",
  123. "2.4.0" => "20.08.2017 new sub for entries in local fhemlog only including verbose support ",
  124. "2.3.1" => "19.08.2017 commandref revised ",
  125. "2.3.0" => "18.08.2017 new parameter 'ident' in Define to indentify sylog source ",
  126. "2.2.0" => "17.08.2017 set BSD data length, set only acceptable characters (USASCII) in payload ",
  127. "2.0.0" => "16.08.2017 create syslog without perl module SYS::SYSLOG ",
  128. "1.1.0" => "26.07.2017 add regex search to sub Log2Syslog_fhemlog ",
  129. "1.0.0" => "25.07.2017 initial version "
  130. );
  131. # Hint Hash
  132. our %Log2Syslog_vHintsExt = (
  133. "3" => "The <a href=\"https://tools.ietf.org/pdf/rfc5425.pdf\">RFC5425</a> TLS Transport Protocol",
  134. "2" => "The basics of <a href=\"https://tools.ietf.org/html/rfc3164\">RFC3164 (BSD)</a> protocol",
  135. "1" => "Informations about <a href=\"https://tools.ietf.org/html/rfc5424\">RFC5424 (IETF)</a> syslog protocol"
  136. );
  137. # Mappinghash BSD-Formatierung Monat
  138. our %Log2Syslog_BSDMonth = (
  139. "01" => "Jan",
  140. "02" => "Feb",
  141. "03" => "Mar",
  142. "04" => "Apr",
  143. "05" => "May",
  144. "06" => "Jun",
  145. "07" => "Jul",
  146. "08" => "Aug",
  147. "09" => "Sep",
  148. "10" => "Oct",
  149. "11" => "Nov",
  150. "12" => "Dec",
  151. "Jan" => "01",
  152. "Feb" => "02",
  153. "Mar" => "03",
  154. "Apr" => "04",
  155. "May" => "05",
  156. "Jun" => "06",
  157. "Jul" => "07",
  158. "Aug" => "08",
  159. "Sep" => "09",
  160. "Oct" => "10",
  161. "Nov" => "11",
  162. "Dec" => "12"
  163. );
  164. # Mappinghash Severity
  165. my %Log2Syslog_Severity = (
  166. "0" => "Emergency",
  167. "1" => "Alert",
  168. "2" => "Critical",
  169. "3" => "Error",
  170. "4" => "Warning",
  171. "5" => "Notice",
  172. "6" => "Informational",
  173. "7" => "Debug",
  174. "Emergency" => "0",
  175. "Alert" => "1",
  176. "Critical" => "2",
  177. "Error" => "3",
  178. "Warning" => "4",
  179. "Notice" => "5",
  180. "Informational" => "6",
  181. "Debug" => "7"
  182. );
  183. # Mappinghash Facility
  184. my %Log2Syslog_Facility = (
  185. "0" => "kernel",
  186. "1" => "user",
  187. "2" => "mail",
  188. "3" => "system",
  189. "4" => "security",
  190. "5" => "syslog",
  191. "6" => "printer",
  192. "7" => "network",
  193. "8" => "UUCP",
  194. "9" => "clock",
  195. "10" => "security",
  196. "11" => "FTP",
  197. "12" => "NTP",
  198. "13" => "log_audit",
  199. "14" => "log_alert",
  200. "15" => "clock",
  201. "16" => "local0",
  202. "17" => "local1",
  203. "18" => "local2",
  204. "19" => "local3",
  205. "20" => "local4",
  206. "21" => "local5",
  207. "22" => "local6",
  208. "23" => "local7"
  209. );
  210. # Längenvorgaben nach RFC3164
  211. my %RFC3164len = ("TAG" => 32, # max. Länge TAG-Feld
  212. "DL" => 1024 # max. Lange Message insgesamt
  213. );
  214. # Längenvorgaben nach RFC5425
  215. my %RFC5425len = ("DL" => 8192, # max. Lange Message insgesamt mit TLS
  216. "HST" => 255, # max. Länge Hostname
  217. "ID" => 48, # max. Länge APP-NAME bzw. Ident
  218. "PID" => 128, # max. Länge Proc-ID
  219. "MID" => 32 # max. Länge MSGID
  220. );
  221. ###############################################################################
  222. # Forward declarations
  223. #
  224. sub Log2Syslog_Log3slog($$$);
  225. ###############################################################################
  226. sub Log2Syslog_Initialize($) {
  227. my ($hash) = @_;
  228. $hash->{DefFn} = "Log2Syslog_Define";
  229. $hash->{UndefFn} = "Log2Syslog_Undef";
  230. $hash->{DeleteFn} = "Log2Syslog_Delete";
  231. $hash->{SetFn} = "Log2Syslog_Set";
  232. $hash->{GetFn} = "Log2Syslog_Get";
  233. $hash->{AttrFn} = "Log2Syslog_Attr";
  234. $hash->{NotifyFn} = "Log2Syslog_eventlog";
  235. $hash->{ReadFn} = "Log2Syslog_Read";
  236. $hash->{AttrList} = "addStateEvent:1,0 ".
  237. "disable:1,0,maintenance ".
  238. "addTimestamp:0,1 ".
  239. "contDelimiter ".
  240. "logFormat:BSD,IETF ".
  241. "makeEvent:no,intern,reading ".
  242. "outputFields:sortable-strict,PRIVAL,FAC,SEV,TS,HOST,DATE,TIME,ID,PID,MID,SDFIELD,CONT ".
  243. "parseProfile:BSD,IETF,TPLink-Switch,raw,ParseFn ".
  244. "parseFn:textField-long ".
  245. "respectSeverity:multiple-strict,Emergency,Alert,Critical,Error,Warning,Notice,Informational,Debug ".
  246. "octetCount:1,0 ".
  247. "ssldebug:0,1,2,3 ".
  248. "sslCertPrefix ".
  249. "TLS:1,0 ".
  250. "timeout ".
  251. "protocol:UDP,TCP ".
  252. "port ".
  253. "rateCalcRerun ".
  254. $readingFnAttributes
  255. ;
  256. return undef;
  257. }
  258. ###############################################################################
  259. sub Log2Syslog_Define($@) {
  260. my ($hash, $def) = @_;
  261. my @a = split("[ \t][ \t]*", $def);
  262. my $name = $hash->{NAME};
  263. return "Error: Perl module ".$MissModulSocket." is missing. Install it on Debian with: sudo apt-get install libio-socket-multicast-perl" if($MissModulSocket);
  264. return "Error: Perl module ".$MissModulNDom." is missing." if($MissModulNDom);
  265. # Example Sender: define splunklog Log2Syslog splunk.myds.me ident:Prod event:.* fhem:.*
  266. # Example Collector: define SyslogServer Log2Syslog
  267. delete($hash->{HELPER}{EVNTLOG});
  268. delete($hash->{HELPER}{FHEMLOG});
  269. delete($hash->{HELPER}{IDENT});
  270. $hash->{MYHOST} = hostname(); # eigener Host (lt. RFC nur Hostname f. BSD)
  271. my $myfqdn = hostfqdn(); # MYFQDN eigener Host (f. IETF)
  272. $hash->{MYFQDN} = $myfqdn?$myfqdn:$hash->{MYHOST};
  273. if(int(@a)-3 < 0){
  274. # Einrichtung Servermode (Collector)
  275. Log2Syslog_Log3slog ($hash, 3, "Log2Syslog $name - entering Syslog servermode ...");
  276. $hash->{MODEL} = "Collector";
  277. $hash->{PROFILE} = "IETF";
  278. readingsSingleUpdate ($hash, 'Parse_Err_No', 0, 1); # Fehlerzähler für Parse-Errors auf 0
  279. Log2Syslog_initServer("$name,global");
  280. } else {
  281. # Sendermode
  282. $hash->{MODEL} = "Sender";
  283. Log2Syslog_setidrex($hash,$a[3]) if($a[3]);
  284. Log2Syslog_setidrex($hash,$a[4]) if($a[4]);
  285. Log2Syslog_setidrex($hash,$a[5]) if($a[5]);
  286. eval { "Hallo" =~ m/^$hash->{HELPER}{EVNTLOG}$/ } if($hash->{HELPER}{EVNTLOG});
  287. return "Bad regexp: $@" if($@);
  288. eval { "Hallo" =~ m/^$hash->{HELPER}{FHEMLOG}$/ } if($hash->{HELPER}{FHEMLOG});
  289. return "Bad regexp: $@" if($@);
  290. return "Bad regexp: starting with *"
  291. if((defined($hash->{HELPER}{EVNTLOG}) && $hash->{HELPER}{EVNTLOG} =~ m/^\*/) || (defined($hash->{HELPER}{FHEMLOG}) && $hash->{HELPER}{FHEMLOG} =~ m/^\*/));
  292. # nur Events dieser Devices an NotifyFn weiterleiten, NOTIFYDEV wird gesetzt wenn möglich
  293. notifyRegexpChanged($hash, $hash->{HELPER}{EVNTLOG}) if($hash->{HELPER}{EVNTLOG});
  294. $hash->{PEERHOST} = $a[2]; # Destination Host (Syslog Server)
  295. }
  296. $hash->{SEQNO} = 1; # PROCID in IETF, wird kontinuierlich hochgezählt
  297. $hash->{VERSION} = (reverse sort(keys %Log2Syslog_vNotesIntern))[0];
  298. $logInform{$hash->{NAME}} = "Log2Syslog_fhemlog"; # Funktion die in hash %loginform für $name eingetragen wird
  299. $hash->{HELPER}{SSLVER} = "n.a."; # Initialisierung
  300. $hash->{HELPER}{SSLALGO} = "n.a."; # Initialisierung
  301. $hash->{HELPER}{LTIME} = time(); # Init Timestmp f. Ratenbestimmung
  302. $hash->{HELPER}{OLDSEQNO} = $hash->{SEQNO}; # Init Sequenznummer f. Ratenbestimmung
  303. $hash->{HELPER}{OLDSTATE} = "initialized";
  304. readingsBeginUpdate($hash);
  305. readingsBulkUpdate($hash, "SSL_Version", "n.a.");
  306. readingsBulkUpdate($hash, "SSL_Algorithm", "n.a.");
  307. readingsBulkUpdate($hash, "Transfered_logs_per_minute", 0);
  308. readingsBulkUpdate($hash, "state", "initialized") if($hash->{MODEL}=~/Sender/);
  309. readingsEndUpdate($hash,1);
  310. Log2Syslog_trate($hash); # regelm. Berechnung Transfer Rate starten
  311. return undef;
  312. }
  313. #################################################################################################
  314. # Syslog Collector (Server-Mode) initialisieren
  315. # (im Collector Model)
  316. #################################################################################################
  317. sub Log2Syslog_initServer($) {
  318. my ($a) = @_;
  319. my ($name,$global) = split(",",$a);
  320. my $hash = $defs{$name};
  321. my $err;
  322. RemoveInternalTimer($hash, "Log2Syslog_initServer");
  323. return if(IsDisabled($name) || $hash->{SERVERSOCKET});
  324. if($init_done != 1 || Log2Syslog_IsMemLock($hash)) {
  325. InternalTimer(gettimeofday()+1, "Log2Syslog_initServer", "$name,$global", 0);
  326. return;
  327. }
  328. # Inititialisierung FHEM ist fertig -> Attribute geladen
  329. my $port = AttrVal($name, "TLS", 0)?AttrVal($name, "port", 6514):AttrVal($name, "port", 1514);
  330. my $protocol = lc(AttrVal($name, "protocol", "udp"));
  331. my $lh = ($global ? ($global eq "global" ? undef : $global) : ($hash->{IPV6} ? "::1" : "127.0.0.1"));
  332. Log2Syslog_Log3slog ($hash, 3, "Log2Syslog $name - Opening socket on interface \"$global\" ...");
  333. if($protocol =~ /udp/) {
  334. $hash->{SERVERSOCKET} = IO::Socket::INET->new(
  335. Domain => ($hash->{IPV6} ? AF_INET6() : AF_UNSPEC), # Linux bug
  336. LocalHost => $lh,
  337. Proto => $protocol,
  338. LocalPort => $port,
  339. ReuseAddr => 1
  340. );
  341. if(!$hash->{SERVERSOCKET}) {
  342. $err = "Can't open Syslog Collector at $port: $!";
  343. Log2Syslog_Log3slog ($hash, 1, "Log2Syslog $name - $err");
  344. readingsSingleUpdate ($hash, 'state', $err, 1);
  345. return;
  346. }
  347. $hash->{FD} = $hash->{SERVERSOCKET}->fileno();
  348. $hash->{PORT} = $hash->{SERVERSOCKET}->sockport();
  349. } else {
  350. $lh = "global" if(!$lh);
  351. my $ret = TcpServer_Open($hash,$port,$lh);
  352. if($ret) {
  353. $err = "Can't open Syslog TCP Collector at $port: $ret";
  354. Log2Syslog_Log3slog ($hash, 1, "Log2Syslog $name - $err");
  355. readingsSingleUpdate ($hash, 'state', $err, 1);
  356. return;
  357. }
  358. }
  359. $hash->{PROTOCOL} = $protocol;
  360. $hash->{SEQNO} = 1; # PROCID wird kontinuierlich pro empfangenen Datensatz hochgezählt
  361. $hash->{HELPER}{OLDSEQNO} = $hash->{SEQNO}; # Init Sequenznummer f. Ratenbestimmung
  362. $hash->{INTERFACE} = $lh?$lh:"global";
  363. Log2Syslog_Log3slog ($hash, 3, "Log2Syslog $name - port $hash->{PORT}/$protocol opened for Syslog Collector on interface \"$hash->{INTERFACE}\"");
  364. readingsSingleUpdate ($hash, "state", "initialized", 1);
  365. delete($readyfnlist{"$name.$port"});
  366. $selectlist{"$name.$port"} = $hash;
  367. return;
  368. }
  369. ########################################################################################################
  370. # Syslog Collector Daten empfangen (im Collector-Mode)
  371. #
  372. # !!!!! Achtung !!!!!
  373. # Kontextswitch des $hash beachten: initialer TCP-Server <-> temporärer TCP-Server ohne SERVERSOCKET
  374. #
  375. ########################################################################################################
  376. # called from the global loop, when the select for hash->{FD} reports data
  377. sub Log2Syslog_Read($@) {
  378. my ($hash,$reread) = @_;
  379. my $socket = $hash->{SERVERSOCKET};
  380. my ($err,$sev,$data,$ts,$phost,$pl,$ignore,$st,$len,$evt,$pen);
  381. return if($init_done != 1);
  382. my $mlen = 8192; # maximale Länge des Syslog-Frames als Begrenzung falls kein EOF
  383. # vom Sender initiiert wird (Endlosschleife vermeiden)
  384. if($hash->{TEMPORARY}) {
  385. # temporäre Instanz angelegt durch TcpServer_Accept
  386. $len = 8192;
  387. ($st,$data,$hash) = Log2Syslog_getifdata($hash,$len,$mlen,$reread);
  388. }
  389. my $name = $hash->{NAME};
  390. return if(IsDisabled($name) || Log2Syslog_IsMemLock($hash));
  391. my $pp = AttrVal($name, "parseProfile", "IETF");
  392. my $mevt = AttrVal($name, "makeEvent", "intern"); # wie soll Reading/Event erstellt werden
  393. my $sevevt = AttrVal($name, "respectSeverity", ""); # welcher Schweregrad soll berücksichtigt werden (default: alle)
  394. if($pp =~ /BSD/) {
  395. # BSD-Format
  396. $len = $RFC3164len{DL};
  397. } elsif ($pp =~ /IETF/) {
  398. # IETF-Format
  399. $len = $RFC5425len{DL};
  400. } else {
  401. # raw oder User eigenes Format
  402. $len = 8192;
  403. }
  404. if($socket) {
  405. ($st,$data,$hash) = Log2Syslog_getifdata($hash,$len,$mlen,$reread);
  406. }
  407. if($data) {
  408. # parse Payload
  409. my (@load,$mlen,$msg,$tail);
  410. if($data =~ /^(?<mlen>(\d+))\s(?<tail>.*)/s) {
  411. # Syslog Sätze mit Octet Count -> Transmission of Syslog Messages over TCP https://tools.ietf.org/html/rfc6587
  412. my $i = 0;
  413. $mlen = $+{mlen};
  414. $tail = $+{tail};
  415. $msg = substr($tail,0,$mlen);
  416. chomp $msg;
  417. push @load, $msg;
  418. $tail = substr($tail,$mlen);
  419. Log2Syslog_Log3slog ($hash, 5, "Log2Syslog $name -> LEN$i: $mlen, MSG$i: $msg, TAIL$i: $tail");
  420. while($tail && $tail =~ /^(?<mlen>(\d+))\s(?<tail>.*)/s) {
  421. $i++;
  422. $mlen = $+{mlen};
  423. $tail = $+{tail};
  424. $msg = substr($tail,0,$mlen);
  425. chomp $msg;
  426. push @load, $msg;
  427. $tail = substr($tail,$mlen);
  428. Log2Syslog_Log3slog ($hash, 5, "Log2Syslog $name -> LEN$i: $mlen, MSG$i: $msg, TAIL$i: $tail");
  429. }
  430. } else {
  431. @load = split("[\r\n]",$data);
  432. }
  433. foreach my $line (@load) {
  434. ($err,$ignore,$sev,$phost,$ts,$pl) = Log2Syslog_parsePayload($hash,$line);
  435. $hash->{SEQNO}++;
  436. if($err) {
  437. $pen = ReadingsVal($name, "Parse_Err_No", 0);
  438. $pen++;
  439. readingsSingleUpdate($hash, 'Parse_Err_No', $pen, 1);
  440. $st = "parse error - see logfile";
  441. } elsif ($ignore) {
  442. Log2Syslog_Log3slog ($hash, 5, "Log2Syslog $name -> dataset was ignored by parseFn");
  443. } else {
  444. return if($sevevt && $sevevt !~ m/$sev/); # Message nicht berücksichtigen
  445. $st = "active";
  446. if($mevt =~ /intern/) {
  447. # kein Reading, nur Event
  448. $pl = "$phost: $pl";
  449. Log2Syslog_Trigger($hash,$ts,$pl);
  450. } elsif ($mevt =~ /reading/) {
  451. # Reading, Event abhängig von event-on-.*
  452. readingsSingleUpdate($hash, "MSG_$phost", $pl, 1);
  453. } else {
  454. # Reading ohne Event
  455. readingsSingleUpdate($hash, "MSG_$phost", $pl, 0);
  456. }
  457. }
  458. $evt = ($st eq $hash->{HELPER}{OLDSTATE})?0:1;
  459. readingsSingleUpdate($hash, "state", $st, $evt);
  460. $hash->{HELPER}{OLDSTATE} = $st;
  461. }
  462. }
  463. return;
  464. }
  465. ###############################################################################
  466. # Daten vom Interface holen
  467. #
  468. # Die einzige Aufgabe der Instanz mit SERVERSOCKET ist TcpServer_Accept
  469. # durchzufuehren (und evtl. noch Statistiken). Durch den Accept wird eine
  470. # weitere Instanz des gleichen Typs angelegt die eine Verbindung repraesentiert
  471. # und im ReadFn die eigentliche Arbeit macht:
  472. #
  473. # - ohne SERVERSOCKET dafuer mit CD/FD, PEER und PORT. CD/FD enthaelt den
  474. # neuen Filedeskriptor.
  475. # - mit TEMPORARY (damit es nicht gespeichert wird)
  476. # - SNAME verweist auf die "richtige" Instanz, damit man die Attribute
  477. # abfragen kann.
  478. # - TcpServer_Accept traegt den neuen Filedeskriptor in die globale %selectlist
  479. # ein. Damit wird ReadFn von fhem.pl/select mit dem temporaeren Instanzhash
  480. # aufgerufen, wenn Daten genau bei dieser Verbindung anstehen.
  481. # (sSiehe auch "list TYPE=FHEMWEB", bzw. "man -s2 accept")
  482. #
  483. ###############################################################################
  484. sub Log2Syslog_getifdata($$@) {
  485. my ($hash,$len,$mlen,$reread) = @_;
  486. my $name = $hash->{NAME};
  487. my $socket = $hash->{SERVERSOCKET};
  488. my $protocol = lc(AttrVal($name, "protocol", "udp"));
  489. if($hash->{TEMPORARY}) {
  490. # temporäre Instanz abgelegt durch TcpServer_Accept
  491. $protocol = "tcp";
  492. }
  493. my $st = ReadingsVal($name,"state","active");
  494. my ($data,$ret);
  495. if($socket && $protocol =~ /udp/) {
  496. # UDP Datagramm empfangen
  497. Log2Syslog_Log3slog ($hash, 4, "Log2Syslog $name - ####################################################### ");
  498. Log2Syslog_Log3slog ($hash, 4, "Log2Syslog $name - ######### new Syslog UDP Parsing ######### ");
  499. Log2Syslog_Log3slog ($hash, 4, "Log2Syslog $name - ####################################################### ");
  500. unless($socket->recv($data, $len)) {
  501. Log2Syslog_Log3slog ($hash, 3, "Log2Syslog $name - Seq \"$hash->{SEQNO}\" invalid data: $data");
  502. $data = '' if(length($data) == 0);
  503. $st = "receive error - see logfile";
  504. }
  505. } elsif ($protocol =~ /tcp/) {
  506. if($hash->{SERVERSOCKET}) { # Accept and create a child
  507. my $nhash = TcpServer_Accept($hash, "Log2Syslog");
  508. return ($st,$data,$hash) if(!$nhash);
  509. $nhash->{CD}->blocking(0);
  510. if($nhash->{SSL}) {
  511. my $sslver = $nhash->{CD}->get_sslversion();
  512. my $sslalgo = $nhash->{CD}->get_fingerprint();
  513. readingsSingleUpdate($hash, "SSL_Version", $sslver, 1);
  514. readingsSingleUpdate($hash, "SSL_Algorithm", $sslalgo, 1);
  515. }
  516. return ($st,$data,$hash);
  517. }
  518. my $sname = $hash->{SNAME};
  519. my $cname = $hash->{NAME};
  520. my $shash = $defs{$sname}; # Hash des Log2Syslog-Devices bei temporärer TCP-Serverinstanz
  521. Log2Syslog_Log3slog ($shash, 4, "Log2Syslog $sname - ####################################################### ");
  522. Log2Syslog_Log3slog ($shash, 4, "Log2Syslog $sname - ######### new Syslog TCP Parsing ######### ");
  523. Log2Syslog_Log3slog ($shash, 4, "Log2Syslog $sname - ####################################################### ");
  524. Log2Syslog_Log3slog ($shash, 4, "Log2Syslog $sname - childname: $cname");
  525. $st = ReadingsVal($sname,"state","active");
  526. my $c = $hash->{CD};
  527. if($c) {
  528. $shash->{HELPER}{TCPPADDR} = $hash->{PEER};
  529. if(!$reread) {
  530. my $buf;
  531. my $off = 0;
  532. $ret = sysread($c, $buf, $len); # returns undef on error, 0 at end of file and Integer, number of bytes read on success.
  533. if(!defined($ret) && $! == EWOULDBLOCK ){
  534. # error
  535. $hash->{wantWrite} = 1 if(TcpServer_WantWrite($hash));
  536. $hash = $shash;
  537. return ($st,undef,$hash);
  538. } elsif (!$ret) {
  539. # end of file
  540. CommandDelete(undef, $cname);
  541. $hash = $shash;
  542. Log2Syslog_Log3slog ($shash, 4, "Log2Syslog $sname - Connection closed for $cname: ".(defined($ret) ? 'EOF' : $!));
  543. return ($st,undef,$hash);
  544. }
  545. $hash->{BUF} .= $buf;
  546. if($hash->{SSL} && $c->can('pending')) {
  547. while($c->pending()) {
  548. sysread($c, $buf, 1024);
  549. $hash->{BUF} .= $buf;
  550. }
  551. }
  552. $data = $hash->{BUF};
  553. delete $hash->{BUF};
  554. $hash = $shash;
  555. Log2Syslog_Log3slog ($shash, 5, "Log2Syslog $sname - Buffer content:\n$data");
  556. }
  557. }
  558. } else {
  559. $st = "error - no socket opened";
  560. $data = '';
  561. }
  562. return ($st,$data,$hash);
  563. }
  564. ###############################################################################
  565. # Parsen Payload für Syslog-Server
  566. # (im Collector Model)
  567. ###############################################################################
  568. sub Log2Syslog_parsePayload($$) {
  569. my ($hash,$data) = @_;
  570. my $name = $hash->{NAME};
  571. my $pp = AttrVal($name, "parseProfile", "IETF");
  572. my $severity = "";
  573. my $facility = "";
  574. my @evf = split(",",AttrVal($name, "outputFields", "FAC,SEV,ID,CONT")); # auszugebene Felder im Event/Reading
  575. my $ignore = 0;
  576. my ($Mmm,$dd,$delimiter,$day,$ietf,$err,$pl,$tail);
  577. # Hash zur Umwandlung Felder in deren Variablen
  578. my ($prival,$ts,$host,$date,$time,$id,$pid,$mid,$sdfield,$cont);
  579. my $fac = "";
  580. my $sev = "";
  581. my %fh = (PRIVAL => \$prival,
  582. FAC => \$fac,
  583. SEV => \$sev,
  584. TS => \$ts,
  585. HOST => \$host,
  586. DATE => \$date,
  587. TIME => \$time,
  588. ID => \$id,
  589. PID => \$pid,
  590. MID => \$mid,
  591. SDFIELD => \$sdfield,
  592. CONT => \$cont,
  593. DATA => \$data
  594. );
  595. # Sender Host / IP-Adresse ermitteln, $phost wird Reading im Event
  596. my ($phost) = Log2Syslog_evalPeer($hash);
  597. Log2Syslog_Log3slog ($hash, 4, "Log2Syslog $name - raw message -> $data");
  598. my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); # Istzeit Ableitung
  599. $year = $year+1900;
  600. if ($pp =~ /raw/) {
  601. Log2Syslog_Log3slog($name, 4, "$name - $data");
  602. $ts = TimeNow();
  603. $pl = $data;
  604. } elsif ($pp eq "BSD") {
  605. # BSD Protokollformat https://tools.ietf.org/html/rfc3164
  606. # Beispiel data "<$prival>$month $day $time $myhost $id: $otp"
  607. $data =~ /^<(?<prival>\d{1,3})>(?<tail>.*)$/;
  608. $prival = $+{prival}; # must
  609. $tail = $+{tail};
  610. $tail =~ /^((?<month>\w{3})\s+(?<day>\d{1,2})\s+(?<time>\d{2}:\d{2}:\d{2}))?\s+(?<tail>.*)$/;
  611. $Mmm = $+{month}; # should
  612. $dd = $+{day}; # should
  613. $time = $+{time}; # should
  614. $tail = $+{tail};
  615. if( $Mmm && $dd && $time ) {
  616. my $month = $Log2Syslog_BSDMonth{$Mmm};
  617. $day = (length($dd) == 1)?("0".$dd):$dd;
  618. $ts = "$year-$month-$day $time";
  619. }
  620. if($ts) {
  621. # Annahme: wenn Timestamp gesetzt, wird der Rest der Message ebenfalls dem Standard entsprechen
  622. $tail =~ /^(?<host>[^\s]*)?\s(?<tail>.*)$/;
  623. $host = $+{host}; # should
  624. $tail = $+{tail};
  625. $tail =~ /^(?<id>(\w*))?(?<cont>(\[\w*\]:|:\s).*)$/;
  626. $id = $+{id}; # should
  627. if($id) {
  628. $id = substr($id,0, ($RFC3164len{TAG}-1)); # Länge TAG-Feld nach RFC begrenzen
  629. $cont = $+{cont}; # should
  630. } else {
  631. $cont = $tail;
  632. }
  633. } else {
  634. # andernfalls eher kein Standardaufbau
  635. $cont = $tail;
  636. }
  637. if(!$prival) {
  638. $err = 1;
  639. Log2Syslog_Log3slog ($hash, 2, "Log2Syslog $name - error parse msg -> $data");
  640. } else {
  641. $cont =~ s/^(:\s*)(.*)$/$2/;
  642. if(looks_like_number($prival)) {
  643. $facility = int($prival/8) if($prival >= 0 && $prival <= 191);
  644. $severity = $prival-($facility*8);
  645. $fac = $Log2Syslog_Facility{$facility};
  646. $sev = $Log2Syslog_Severity{$severity};
  647. } else {
  648. $err = 1;
  649. Log2Syslog_Log3slog ($hash, 1, "Log2Syslog $name - error parse msg -> $data");
  650. }
  651. no warnings 'uninitialized';
  652. Log2Syslog_Log3slog($name, 4, "$name - parsed message -> FAC: $fac, SEV: $sev, MM: $Mmm, Day: $dd, TIME: $time, TS: $ts, HOST: $host, ID: $id, CONT: $cont");
  653. $host = "" if($host eq "-");
  654. use warnings;
  655. $phost = $host?$host:$phost;
  656. # Payload zusammenstellen für Event/Reading
  657. $pl = "";
  658. my $i = 0;
  659. foreach my $f (@evf) {
  660. if(${$fh{$f}}) {
  661. $pl .= " || " if($i);
  662. $pl .= "$f: ".${$fh{$f}};
  663. $i++;
  664. }
  665. }
  666. }
  667. } elsif ($pp eq "IETF") {
  668. # IETF Protokollformat https://tools.ietf.org/html/rfc5424
  669. # Beispiel data "<14>1 2018-08-09T21:45:08+02:00 SDS1 Connection - - [synolog@6574 synotype="Connection" luser="apiuser" event="User [apiuser\] logged in from [192.168.2.45\] via [DSM\]."][meta sequenceId="1"] apiuser: User [apiuser] logged in from [192.168.2.45] via [DSM].";
  670. # $data =~ /^<(?<prival>\d{1,3})>(?<ietf>\d+)\s(?<date>\d{4}-\d{2}-\d{2})T(?<time>\d{2}:\d{2}:\d{2})\S*\s(?<host>\S*)\s(?<id>\S*)\s(?<pid>\S*)\s(?<mid>\S*)\s(?<sdfield>(\[.*?(?!\\\]).\]|-))\s(?<cont>.*)$/;
  671. $data =~ /^<(?<prival>\d{1,3})>(?<ietf>\d{0,2})\s(?<cont>.*)$/;
  672. $prival = $+{prival}; # must
  673. $ietf = $+{ietf}; # should
  674. if($prival && $ietf) {
  675. # Standard IETF-Syslog incl. VERSION
  676. if($ietf == 1) {
  677. $data =~ /^<(?<prival>\d{1,3})>(?<ietf>\d{0,2})\s?(?<date>\d{4}-\d{2}-\d{2})T(?<time>\d{2}:\d{2}:\d{2})\S*\s(?<host>\S*)\s(?<id>\S*)\s?(?<pid>\S*)\s?(?<mid>\S*)\s?(?<sdfield>(\[.*?(?!\\\]).\]|-))\s(?<cont>.*)$/;
  678. $prival = $+{prival}; # must
  679. $ietf = $+{ietf}; # should
  680. $date = $+{date}; # must
  681. $time = $+{time}; # must
  682. $host = $+{host}; # should
  683. $id = $+{id}; # should
  684. $pid = $+{pid}; # should
  685. $mid = $+{mid}; # should
  686. $sdfield = $+{sdfield}; # must
  687. $cont = $+{cont}; # should
  688. } else {
  689. $err = 1;
  690. Log2Syslog_Log3slog ($hash, 1, "Log2Syslog $name - new IETF version detected, inform Log2Syslog Maintainer");
  691. }
  692. } else {
  693. # IETF-Syslog ohne VERSION
  694. $data =~ /^<(?<prival>\d{1,3})>(?<date>\d{4}-\d{2}-\d{2})T(?<time>\d{2}:\d{2}:\d{2})\S*\s(?<host>\S*)\s(?<id>\S*)\s?(?<pid>\S*)\s?(?<mid>\S*)\s?(?<sdfield>(\[.*?(?!\\\]).\]|-))?\s(?<cont>.*)$/;
  695. $prival = $+{prival}; # must
  696. $date = $+{date}; # must
  697. $time = $+{time}; # must
  698. $host = $+{host}; # should
  699. $id = $+{id}; # should
  700. $pid = $+{pid}; # should
  701. $mid = $+{mid}; # should
  702. $sdfield = $+{sdfield}; # should
  703. $cont = $+{cont}; # should
  704. }
  705. if(!$prival || !$date || !$time) {
  706. $err = 1;
  707. Log2Syslog_Log3slog ($hash, 2, "Log2Syslog $name - error parse msg -> $data");
  708. no warnings 'uninitialized';
  709. Log2Syslog_Log3slog ($hash, 5, "Log2Syslog $name - parsed fields -> PRI: $prival, IETF: $ietf, DATE: $date, TIME: $time, HOST: $host, ID: $id, PID: $pid, MID: $mid, SDFIELD: $sdfield, CONT: $cont");
  710. use warnings;
  711. } else {
  712. $ts = "$date $time";
  713. if(looks_like_number($prival)) {
  714. $facility = int($prival/8) if($prival >= 0 && $prival <= 191);
  715. $severity = $prival-($facility*8);
  716. $fac = $Log2Syslog_Facility{$facility};
  717. $sev = $Log2Syslog_Severity{$severity};
  718. } else {
  719. $err = 1;
  720. Log2Syslog_Log3slog ($hash, 2, "Log2Syslog $name - error parse msg -> $data");
  721. }
  722. # Längenbegrenzung nach RFC5424
  723. $id = substr($id,0, ($RFC5425len{ID}-1));
  724. $pid = substr($pid,0, ($RFC5425len{PID}-1));
  725. $mid = substr($mid,0, ($RFC5425len{MID}-1));
  726. $host = substr($host,0, ($RFC5425len{HST}-1));
  727. no warnings 'uninitialized';
  728. Log2Syslog_Log3slog($name, 4, "$name - parsed message -> FAC: $fac, SEV: $sev, TS: $ts, HOST: $host, ID: $id, PID: $pid, MID: $mid, SDFIELD: $sdfield, CONT: $cont");
  729. $host = "" if($host eq "-");
  730. use warnings;
  731. $phost = $host?$host:$phost;
  732. # Payload zusammenstellen für Event/Reading
  733. $pl = "";
  734. my $i = 0;
  735. foreach my $f (@evf) {
  736. if(${$fh{$f}}) {
  737. $pl .= " || " if($i);
  738. $pl .= "$f: ".${$fh{$f}};
  739. $i++;
  740. }
  741. }
  742. }
  743. } elsif ($pp eq "TPLink-Switch") {
  744. # Parser für TPLink Switch
  745. # Beispiel data "<131>2018-08-10 09:03:58 10.0.x.y 31890 Login the web by admin on web (10.0.x.y).";
  746. $data =~ /^<(?<prival>\d{1,3})>(?<date>\d{4}-\d{2}-\d{2})\s(?<time>\d{2}:\d{2}:\d{2})\s(?<host>\S*)\s(?<id>\S*)\s(?<cont>.*)$/;
  747. $prival = $+{prival}; # must
  748. $date = $+{date}; # must
  749. $time = $+{time}; # must
  750. $host = $+{host}; # should
  751. $id = $+{id}; # should
  752. $cont = $+{cont}; # should
  753. if(!$prival || !$date || !$time) {
  754. $err = 1;
  755. Log2Syslog_Log3slog ($hash, 2, "Log2Syslog $name - error parse msg -> $data");
  756. } else {
  757. $ts = "$date $time";
  758. if(looks_like_number($prival)) {
  759. $facility = int($prival/8) if($prival >= 0 && $prival <= 191);
  760. $severity = $prival-($facility*8);
  761. $fac = $Log2Syslog_Facility{$facility};
  762. $sev = $Log2Syslog_Severity{$severity};
  763. } else {
  764. $err = 1;
  765. Log2Syslog_Log3slog ($hash, 2, "Log2Syslog $name - error parse msg -> $data");
  766. }
  767. no warnings 'uninitialized';
  768. Log2Syslog_Log3slog($name, 4, "$name - parsed message -> FAC: $fac, SEV: $sev, TS: $ts, HOST: $host, ID: $id, CONT: $cont");
  769. $host = "" if($host eq "-");
  770. use warnings;
  771. $phost = $host?$host:$phost;
  772. # Payload zusammenstellen für Event/Reading
  773. $pl = "";
  774. my $i = 0;
  775. foreach my $f (@evf) {
  776. if(${$fh{$f}}) {
  777. $pl .= " || " if($i);
  778. $pl .= "$f: ".${$fh{$f}};
  779. $i++;
  780. }
  781. }
  782. }
  783. } elsif ($pp eq "ParseFn") {
  784. # user spezifisches Parsing
  785. my $parseFn = AttrVal( $name, "parseFn", "" );
  786. $ts = TimeNow();
  787. if( $parseFn =~ m/^\s*(\{.*\})\s*$/s ) {
  788. $parseFn = $1;
  789. } else {
  790. $parseFn = '';
  791. }
  792. if($parseFn ne '') {
  793. my $PRIVAL = "";
  794. my $TS = $ts;
  795. my $DATE = "";
  796. my $TIME = "";
  797. my $HOST = "";
  798. my $ID = "";
  799. my $PID = "";
  800. my $MID = "";
  801. my $CONT = "";
  802. my $FAC = "";
  803. my $SEV = "";
  804. my $DATA = $data;
  805. my $SDFIELD = "";
  806. my $IGNORE = 0;
  807. eval $parseFn;
  808. if($@) {
  809. Log2Syslog_Log3slog ($hash, 2, "Log2Syslog $name -> error parseFn: $@");
  810. $err = 1;
  811. }
  812. $prival = $PRIVAL if($PRIVAL =~ /\d{1,3}/);
  813. $date = $DATE if($DATE =~ /^(\d{4})-(\d{2})-(\d{2})$/);
  814. $time = $TIME if($TIME =~ /^(\d{2}):(\d{2}):(\d{2})$/);
  815. $ts = ($TS =~ /^(\d{4})-(\d{2})-(\d{2})\s(\d{2}):(\d{2}):(\d{2})$/)?$TS:($date && $time)?"$date $time":$ts;
  816. $host = $HOST if(defined $HOST);
  817. $id = $ID if(defined $ID);
  818. $pid = $PID if(defined $PID);
  819. $mid = $MID if(defined $MID);
  820. $cont = $CONT if(defined $CONT);
  821. $fac = $FAC if(defined $FAC);
  822. $sev = $SEV if(defined $SEV);
  823. $sdfield = $SDFIELD if(defined $SDFIELD);
  824. $ignore = $IGNORE if($IGNORE =~ /\d/);
  825. if($prival && looks_like_number($prival)) {
  826. $facility = int($prival/8) if($prival >= 0 && $prival <= 191);
  827. $severity = $prival-($facility*8);
  828. $fac = $Log2Syslog_Facility{$facility};
  829. $sev = $Log2Syslog_Severity{$severity};
  830. } else {
  831. $err = 1;
  832. Log2Syslog_Log3slog ($hash, 2, "Log2Syslog $name - error parse msg -> $data");
  833. }
  834. Log2Syslog_Log3slog($name, 4, "$name - parsed message -> FAC: $fac, SEV: $sev, TS: $ts, HOST: $host, ID: $id, PID: $pid, MID: $mid, CONT: $cont");
  835. $phost = $host?$host:$phost;
  836. # auszugebene Felder im Event/Reading
  837. my $ef = "PRIVAL,FAC,SEV,TS,HOST,DATE,TIME,ID,PID,MID,SDFIELD,CONT";
  838. @evf = split(",",AttrVal($name, "outputFields", $ef));
  839. # Payload zusammenstellen für Event/Reading
  840. $pl = "";
  841. my $i = 0;
  842. foreach my $f (@evf) {
  843. if(${$fh{$f}}) {
  844. $pl .= " || " if($i);
  845. $pl .= "$f: ".${$fh{$f}};
  846. $i++;
  847. }
  848. }
  849. } else {
  850. $err = 1;
  851. Log2Syslog_Log3slog ($hash, 1, "Log2Syslog $name - no parseFn defined.");
  852. }
  853. }
  854. return ($err,$ignore,$sev,$phost,$ts,$pl);
  855. }
  856. #################################################################################################
  857. # Syslog Collector Events erzeugen
  858. # (im Collector Model)
  859. #################################################################################################
  860. sub Log2Syslog_Trigger($$$) {
  861. my ($hash,$ts,$pl) = @_;
  862. my $name = $hash->{NAME};
  863. my $no_replace = 1; # Ersetzung von Events durch das Attribut eventMap verhindern
  864. if($hash->{CHANGED}) {
  865. push @{$hash->{CHANGED}}, $pl;
  866. } else {
  867. $hash->{CHANGED}[0] = $pl;
  868. }
  869. if($hash->{CHANGETIME}) {
  870. push @{$hash->{CHANGETIME}}, $ts;
  871. } else {
  872. $hash->{CHANGETIME}[0] = $ts;
  873. }
  874. my $ret = DoTrigger($name, undef, $no_replace);
  875. return;
  876. }
  877. ###############################################################################
  878. # Undef Funktion
  879. ###############################################################################
  880. sub Log2Syslog_Undef($$) {
  881. my ($hash, $name) = @_;
  882. RemoveInternalTimer($hash);
  883. Log2Syslog_closesock($hash,1); # Clientsocket schließen
  884. Log2Syslog_downServer($hash,1); # Serversocket schließen, kill children
  885. return undef;
  886. }
  887. ###############################################################################
  888. # Collector-Socket schließen
  889. ###############################################################################
  890. sub Log2Syslog_downServer($;$) {
  891. my ($hash,$delchildren) = @_;
  892. my $name = $hash->{NAME};
  893. my $port = $hash->{PORT};
  894. my $protocol = $hash->{PROTOCOL};
  895. my $ret;
  896. return if(!$hash->{SERVERSOCKET} || $hash->{MODEL} !~ /Collector/);
  897. Log2Syslog_Log3slog ($hash, 3, "Log2Syslog $name - Closing server socket $protocol/$port ...");
  898. if($protocol =~ /tcp/) {
  899. TcpServer_Close($hash);
  900. delete($hash->{CONNECTS});
  901. delete($hash->{SERVERSOCKET});
  902. if($delchildren) {
  903. my @children = devspec2array($name."_.*");
  904. foreach (@children) {
  905. my $child = $_;
  906. if($child ne $name."_.*") {
  907. CommandDelete(undef, $child);
  908. Log2Syslog_Log3slog ($hash, 3, "Log2Syslog $name - child instance $child deleted.");
  909. }
  910. }
  911. delete($hash->{HELPER}{SSLALGO});
  912. delete($hash->{HELPER}{SSLVER});
  913. readingsSingleUpdate($hash, "SSL_Version", "n.a.", 1);
  914. readingsSingleUpdate($hash, "SSL_Algorithm", "n.a.", 1);
  915. }
  916. return;
  917. }
  918. $ret = $hash->{SERVERSOCKET}->close();
  919. Log2Syslog_Log3slog ($hash, 1, "Log2Syslog $name - Can't close Syslog Collector at port $port: $!") if(!$ret);
  920. delete($hash->{SERVERSOCKET});
  921. delete($selectlist{"$name.$port"});
  922. delete($readyfnlist{"$name.$port"});
  923. delete($hash->{FD});
  924. return;
  925. }
  926. ###############################################################################
  927. # Delete Funktion
  928. ###############################################################################
  929. sub Log2Syslog_Delete($$) {
  930. my ($hash, $arg) = @_;
  931. delete $logInform{$hash->{NAME}};
  932. return undef;
  933. }
  934. ###############################################################################
  935. # Set
  936. ###############################################################################
  937. sub Log2Syslog_Set($@) {
  938. my ($hash, @a) = @_;
  939. return "\"set X\" needs at least an argument" if ( @a < 2 );
  940. my $name = $a[0];
  941. my $opt = $a[1];
  942. my $prop = $a[2];
  943. my $setlist = "Unknown argument $opt, choose one of ".
  944. "reopen:noArg ".
  945. (($hash->{MODEL} =~ /Sender/)?"sendTestMessage ":"")
  946. ;
  947. return if(AttrVal($name, "disable", "") eq "1");
  948. if($opt =~ /sendTestMessage/) {
  949. my $own;
  950. if ($prop) {
  951. shift @a;
  952. shift @a;
  953. $own = join(" ",@a);
  954. }
  955. Log2Syslog_sendTestMsg($hash,$own);
  956. } elsif($opt =~ /reopen/) {
  957. $hash->{HELPER}{MEMLOCK} = 1;
  958. InternalTimer(gettimeofday()+2, "Log2Syslog_deleteMemLock", $hash, 0);
  959. Log2Syslog_closesock($hash,1); # Clientsocket schließen
  960. Log2Syslog_downServer($hash,1); # Serversocket schließen
  961. if($hash->{MODEL} =~ /Collector/) { # Serversocket öffnen
  962. InternalTimer(gettimeofday()+0.5, "Log2Syslog_initServer", "$name,global", 0);
  963. readingsSingleUpdate ($hash, 'Parse_Err_No', 0, 1); # Fehlerzähler für Parse-Errors auf 0
  964. }
  965. } else {
  966. return "$setlist";
  967. }
  968. return undef;
  969. }
  970. ###############################################################################
  971. # Get
  972. ###############################################################################
  973. sub Log2Syslog_Get($@) {
  974. my ($hash, @a) = @_;
  975. return "\"get X\" needs at least an argument" if ( @a < 2 );
  976. my $name = $a[0];
  977. my $opt = $a[1];
  978. my $prop = $a[2];
  979. my $st;
  980. my $getlist = "Unknown argument $opt, choose one of ".
  981. (($hash->{MODEL} !~ /Collector/)?"certInfo:noArg ":"").
  982. "versionNotes:noArg "
  983. ;
  984. return if(AttrVal($name, "disable", "") eq "1");
  985. my($sock,$cert,@certs);
  986. if ($opt =~ /certInfo/) {
  987. if(ReadingsVal($name,"SSL_Version","n.a.") ne "n.a.") {
  988. ($sock,$st) = Log2Syslog_opensock($hash,0);
  989. if($sock) {
  990. $cert = $sock->dump_peer_certificate();
  991. # Log2Syslog_closesock($hash);
  992. }
  993. }
  994. return $cert if($cert);
  995. return "no SSL session has been created";
  996. } elsif ($opt =~ /versionNotes/) {
  997. my $header = "<b>Module release information table</b><br>";
  998. my $header1 = "<b>Helpful hints</b><br>";
  999. my $i;
  1000. # Ausgabetabelle erstellen
  1001. my ($ret,$val0,$val1);
  1002. $ret = "<html>";
  1003. $ret .= sprintf("<div class=\"makeTable wide\"; style=\"text-align:left\">$header1 <br>");
  1004. $ret .= "<table class=\"block wide internals\">";
  1005. $ret .= "<tbody>";
  1006. $ret .= "<tr class=\"even\">";
  1007. $i = 0;
  1008. foreach my $key (reverse sort(keys %Log2Syslog_vHintsExt)) {
  1009. $val0 = $Log2Syslog_vHintsExt{$key};
  1010. $ret .= sprintf("<td style=\"vertical-align:top\"><b>$key</b> </td><td style=\"vertical-align:top\">$val0</td>" );
  1011. $ret .= "</tr>";
  1012. $i++;
  1013. if ($i & 1) {
  1014. # $i ist ungerade
  1015. $ret .= "<tr class=\"odd\">";
  1016. } else {
  1017. $ret .= "<tr class=\"even\">";
  1018. }
  1019. }
  1020. $ret .= "</tr>";
  1021. $ret .= "</tbody>";
  1022. $ret .= "</table>";
  1023. $ret .= "</div>";
  1024. $ret .= sprintf("<div class=\"makeTable wide\"; style=\"text-align:left\">$header <br>");
  1025. $ret .= "<table class=\"block wide internals\">";
  1026. $ret .= "<tbody>";
  1027. $ret .= "<tr class=\"even\">";
  1028. $i = 0;
  1029. foreach my $key (reverse sort(keys %Log2Syslog_vNotesExtern)) {
  1030. ($val0,$val1) = split(/\s/,$Log2Syslog_vNotesExtern{$key},2);
  1031. $ret .= sprintf("<td style=\"vertical-align:top\"><b>$key</b> </td><td style=\"vertical-align:top\">$val0 </td><td>$val1</td>" );
  1032. $ret .= "</tr>";
  1033. $i++;
  1034. if ($i & 1) {
  1035. # $i ist ungerade
  1036. $ret .= "<tr class=\"odd\">";
  1037. } else {
  1038. $ret .= "<tr class=\"even\">";
  1039. }
  1040. }
  1041. $ret .= "</tr>";
  1042. $ret .= "</tbody>";
  1043. $ret .= "</table>";
  1044. $ret .= "</div>";
  1045. $ret .= "</html>";
  1046. return $ret;
  1047. } else {
  1048. return "$getlist";
  1049. }
  1050. return undef;
  1051. }
  1052. ###############################################################################
  1053. sub Log2Syslog_Attr ($$$$) {
  1054. my ($cmd,$name,$aName,$aVal) = @_;
  1055. my $hash = $defs{$name};
  1056. my ($do,$st);
  1057. # $cmd can be "del" or "set"
  1058. # $name is device name
  1059. # aName and aVal are Attribute name and value
  1060. if ($cmd eq "set" && $hash->{MODEL} !~ /Collector/ && $aName =~ /parseProfile|parseFn|outputFields|makeEvent/) {
  1061. return "\"$aName\" is only valid for model \"Collector\"";
  1062. }
  1063. if ($cmd eq "set" && $hash->{MODEL} =~ /Collector/ && $aName =~ /addTimestamp|contDelimiter|addStateEvent|logFormat|octetCount|ssldebug|timeout/) {
  1064. return "\"$aName\" is only valid for model \"Sender\"";
  1065. }
  1066. if ($aName eq "disable") {
  1067. if($cmd eq "set") {
  1068. return "Mode \"$aVal\" is only valid for model \"Sender\"" if($aVal eq "maintenance" && $hash->{MODEL} !~ /Sender/);
  1069. $do = $aVal?1:0;
  1070. }
  1071. $do = 0 if($cmd eq "del");
  1072. $st = ($do&&$aVal=~/maintenance/)?"maintenance":($do&&$aVal==1)?"disabled":"initialized";
  1073. $hash->{HELPER}{MEMLOCK} = 1;
  1074. InternalTimer(gettimeofday()+2, "Log2Syslog_deleteMemLock", $hash, 0);
  1075. if($do==0 || $aVal=~/maintenance/) {
  1076. if($hash->{MODEL} =~ /Collector/) {
  1077. Log2Syslog_downServer($hash,1); # Serversocket schließen und wieder öffnen
  1078. InternalTimer(gettimeofday()+0.5, "Log2Syslog_initServer", "$name,global", 0);
  1079. }
  1080. } else {
  1081. Log2Syslog_closesock($hash,1); # Clientsocket schließen
  1082. Log2Syslog_downServer($hash); # Serversocket schließen
  1083. }
  1084. }
  1085. if ($aName eq "TLS") {
  1086. if($cmd eq "set") {
  1087. $do = ($aVal) ? 1 : 0;
  1088. }
  1089. $do = 0 if($cmd eq "del");
  1090. if ($do == 0) {
  1091. delete $hash->{SSL};
  1092. } else {
  1093. if($hash->{MODEL} =~ /Collector/) {
  1094. $attr{$name}{protocol} = "TCP" if(AttrVal($name, "protocol", "UDP") ne "TCP");
  1095. TcpServer_SetSSL($hash);
  1096. }
  1097. }
  1098. $hash->{HELPER}{MEMLOCK} = 1;
  1099. InternalTimer(gettimeofday()+2, "Log2Syslog_deleteMemLock", $hash, 0);
  1100. Log2Syslog_closesock($hash,1); # Clientsocket schließen
  1101. Log2Syslog_downServer($hash,1); # Serversocket schließen
  1102. if($hash->{MODEL} =~ /Collector/) {
  1103. InternalTimer(gettimeofday()+0.5, "Log2Syslog_initServer", "$name,global", 0); # Serversocket öffnen
  1104. readingsSingleUpdate ($hash, 'Parse_Err_No', 0, 1); # Fehlerzähler für Parse-Errors auf 0
  1105. }
  1106. }
  1107. if ($aName =~ /rateCalcRerun/) {
  1108. unless ($aVal =~ /^[0-9]+$/) { return "Value of $aName is not valid. Use only figures 0-9 without decimal places !";}
  1109. $_[3] = 60 if($aVal < 60);
  1110. RemoveInternalTimer($hash, "Log2Syslog_trate");
  1111. InternalTimer(gettimeofday()+5, "Log2Syslog_trate", $hash, 0);
  1112. }
  1113. if ($cmd eq "set" && $aName =~ /port|timeout/) {
  1114. if($aVal !~ m/^\d+$/) { return " The Value of \"$aName\" is not valid. Use only figures !";}
  1115. $hash->{HELPER}{MEMLOCK} = 1;
  1116. InternalTimer(gettimeofday()+2, "Log2Syslog_deleteMemLock", $hash, 0);
  1117. if($aName =~ /port/ && $hash->{MODEL} =~ /Collector/ && $init_done) {
  1118. return "$aName \"$aVal\" is not valid because privileged ports are only usable by super users. Use a port grater than 1023." if($aVal < 1024);
  1119. Log2Syslog_downServer($hash,1); # Serversocket schließen
  1120. InternalTimer(gettimeofday()+0.5, "Log2Syslog_initServer", "$name,global", 0);
  1121. readingsSingleUpdate ($hash, 'Parse_Err_No', 0, 1); # Fehlerzähler für Parse-Errors auf 0
  1122. } elsif ($aName =~ /port/ && $hash->{MODEL} !~ /Collector/) {
  1123. Log2Syslog_closesock($hash,1); # Clientsocket schließen
  1124. }
  1125. }
  1126. if ($aName =~ /protocol/) {
  1127. if($aVal =~ /UDP/) {
  1128. $attr{$name}{TLS} = 0 if(AttrVal($name, "TLS", 0));
  1129. }
  1130. $hash->{HELPER}{MEMLOCK} = 1;
  1131. InternalTimer(gettimeofday()+2, "Log2Syslog_deleteMemLock", $hash, 0);
  1132. if($hash->{MODEL} eq "Collector") {
  1133. Log2Syslog_downServer($hash,1); # Serversocket schließen
  1134. InternalTimer(gettimeofday()+0.5, "Log2Syslog_initServer", "$name,global", 0);
  1135. readingsSingleUpdate ($hash, 'Parse_Err_No', 0, 1); # Fehlerzähler für Parse-Errors auf 0
  1136. } else {
  1137. Log2Syslog_closesock($hash,1); # Clientsocket schließen
  1138. }
  1139. }
  1140. if ($cmd eq "set" && $aName =~ /parseFn/) {
  1141. $_[3] = "{$aVal}" if($aVal !~ m/^\{.*\}$/s);
  1142. $aVal = $_[3];
  1143. my %specials = (
  1144. "%IGNORE" => "0",
  1145. "%DATA" => "1",
  1146. "%PRIVAL" => "1",
  1147. "%TS" => "1",
  1148. "%DATE" => "1",
  1149. "%TIME" => "1",
  1150. "%HOST" => "1",
  1151. "%ID" => "1",
  1152. "%PID" => "1",
  1153. "%MID" => "1",
  1154. "%CONT" => "1",
  1155. "%FAC" => "1",
  1156. "%SDFIELD" => "1",
  1157. "%SEV" => "1"
  1158. );
  1159. my $err = perlSyntaxCheck($aVal, %specials);
  1160. return $err if($err);
  1161. }
  1162. if ($aName =~ /parseProfile/) {
  1163. if ($cmd eq "set" && $aVal =~ /ParseFn/) {
  1164. return "You have to define a parse-function via attribute \"parseFn\" first !" if(!AttrVal($name,"parseFn",""));
  1165. }
  1166. if ($cmd eq "set") {
  1167. $hash->{PROFILE} = $aVal;
  1168. } else {
  1169. $hash->{PROFILE} = "IETF";
  1170. }
  1171. readingsSingleUpdate ($hash, 'Parse_Err_No', 0, 1); # Fehlerzähler für Parse-Errors auf 0
  1172. }
  1173. if ($cmd eq "del" && $aName =~ /parseFn/ && AttrVal($name,"parseProfile","") eq "ParseFn" ) {
  1174. return "You use a parse-function via attribute \"parseProfile\". Please change/delete attribute \"parseProfile\" first !";
  1175. }
  1176. if ($aName =~ /makeEvent/) {
  1177. foreach my $key(keys%{$defs{$name}{READINGS}}) {
  1178. delete($defs{$name}{READINGS}{$key}) if($key !~ /state|Transfered_logs_per_minute|SSL_.*|Parse_Err_No/);
  1179. }
  1180. }
  1181. return;
  1182. }
  1183. #################################################################################
  1184. # Eventlogging
  1185. #################################################################################
  1186. sub Log2Syslog_eventlog($$) {
  1187. # $hash is my entry, $dev is the entry of the changed device
  1188. my ($hash,$dev) = @_;
  1189. my $name = $hash->{NAME};
  1190. my $rex = $hash->{HELPER}{EVNTLOG};
  1191. my $st = ReadingsVal($name,"state","active");
  1192. my $sendsev = AttrVal($name, "respectSeverity", ""); # Nachrichten welcher Schweregrade sollen gesendet werden
  1193. my ($prival,$data,$sock,$pid,$sevAstxt);
  1194. if(IsDisabled($name)) {
  1195. $st = AttrVal($name, "disable", "0");
  1196. $st = ($st =~ /maintenance/)?$st:"disabled";
  1197. my $evt = ($st eq $hash->{HELPER}{OLDSTATE})?0:1;
  1198. readingsSingleUpdate($hash, "state", $st, $evt);
  1199. $hash->{HELPER}{OLDSTATE} = $st;
  1200. return;
  1201. }
  1202. if($init_done != 1 || !$rex || $hash->{MODEL} !~ /Sender/ || Log2Syslog_IsMemLock($hash)) {
  1203. return;
  1204. }
  1205. my $events = deviceEvents($dev, AttrVal($name, "addStateEvent", 0));
  1206. return if(!$events);
  1207. my $n = $dev->{NAME};
  1208. my $max = int(@{$events});
  1209. my $tn = $dev->{NTFY_TRIGGERTIME};
  1210. my $ct = $dev->{CHANGETIME};
  1211. ($sock,$st) = Log2Syslog_opensock($hash,0);
  1212. if($sock) {
  1213. for (my $i = 0; $i < $max; $i++) {
  1214. my $txt = $events->[$i];
  1215. $txt = "" if(!defined($txt));
  1216. $txt = Log2Syslog_charfilter($hash,$txt);
  1217. my $tim = (($ct && $ct->[$i]) ? $ct->[$i] : $tn);
  1218. my ($date,$time) = split(" ",$tim);
  1219. if($n =~ m/^$rex$/ || "$n:$txt" =~ m/^$rex$/ || "$tim:$n:$txt" =~ m/^$rex$/) {
  1220. my $otp = "$n $txt";
  1221. $otp = "$tim $otp" if AttrVal($name,'addTimestamp',0);
  1222. ($prival,$sevAstxt) = Log2Syslog_setprival($txt);
  1223. if($sendsev && $sendsev !~ m/$sevAstxt/) {
  1224. # nicht senden wenn Severity nicht in "respectSeverity" enthalten
  1225. Log2Syslog_Log3slog($name, 5, "Log2Syslog $name - Warning - Payload NOT sent due to Message Severity not in attribute \"respectSeverity\"\n");
  1226. next;
  1227. }
  1228. ($data,$pid) = Log2Syslog_setpayload($hash,$prival,$date,$time,$otp,"event");
  1229. next if(!$data);
  1230. my $ret = syswrite ($sock,$data);
  1231. if($ret && $ret > 0) {
  1232. Log2Syslog_Log3slog($name, 4, "Log2Syslog $name - Payload sequence $pid sent\n");
  1233. } else {
  1234. my $err = $!;
  1235. Log2Syslog_Log3slog($name, 3, "Log2Syslog $name - Warning - Payload sequence $pid NOT sent: $err\n");
  1236. $st = "write error: $err";
  1237. }
  1238. }
  1239. }
  1240. Log2Syslog_closesock($hash) if($st =~ /^write error:.*/);
  1241. }
  1242. my $evt = ($st eq $hash->{HELPER}{OLDSTATE})?0:1;
  1243. readingsSingleUpdate($hash, "state", $st, $evt);
  1244. $hash->{HELPER}{OLDSTATE} = $st;
  1245. return "";
  1246. }
  1247. #################################################################################
  1248. # FHEM system logging
  1249. #################################################################################
  1250. sub Log2Syslog_fhemlog($$) {
  1251. my ($name,$raw) = @_;
  1252. my $hash = $defs{$name};
  1253. my $rex = $hash->{HELPER}{FHEMLOG};
  1254. my $st = ReadingsVal($name,"state","active");
  1255. my $sendsev = AttrVal($name, "respectSeverity", ""); # Nachrichten welcher Schweregrade sollen gesendet werden
  1256. my ($prival,$sock,$err,$ret,$data,$pid,$sevAstxt);
  1257. if(IsDisabled($name)) {
  1258. $st = AttrVal($name, "disable", "1");
  1259. $st = ($st =~ /maintenance/)?$st:"disabled";
  1260. my $evt = ($st eq $hash->{HELPER}{OLDSTATE})?0:1;
  1261. readingsSingleUpdate($hash, "state", $st, $evt);
  1262. $hash->{HELPER}{OLDSTATE} = $st;
  1263. return;
  1264. }
  1265. if($init_done != 1 || !$rex || $hash->{MODEL} !~ /Sender/ || Log2Syslog_IsMemLock($hash)) {
  1266. return;
  1267. }
  1268. my ($date,$time,$vbose,undef,$txt) = split(" ",$raw,5);
  1269. $txt = Log2Syslog_charfilter($hash,$txt);
  1270. $date =~ s/\./-/g;
  1271. my $tim = $date." ".$time;
  1272. if($txt =~ m/^$rex$/ || "$vbose: $txt" =~ m/^$rex$/) {
  1273. my $otp = "$vbose: $txt";
  1274. $otp = "$tim $otp" if AttrVal($name,'addTimestamp',0);
  1275. ($prival,$sevAstxt) = Log2Syslog_setprival($txt,$vbose);
  1276. if($sendsev && $sendsev !~ m/$sevAstxt/) {
  1277. # nicht senden wenn Severity nicht in "respectSeverity" enthalten
  1278. Log2Syslog_Log3slog($name, 5, "Log2Syslog $name - Warning - Payload NOT sent due to Message Severity not in attribute \"respectSeverity\"\n");
  1279. return;
  1280. }
  1281. ($data,$pid) = Log2Syslog_setpayload($hash,$prival,$date,$time,$otp,"fhem");
  1282. return if(!$data);
  1283. ($sock,$st) = Log2Syslog_opensock($hash,0);
  1284. if ($sock) {
  1285. $ret = syswrite($sock,$data) if($data);
  1286. if($ret && $ret > 0) {
  1287. Log2Syslog_Log3slog($name, 4, "Log2Syslog $name - Payload sequence $pid sent\n");
  1288. } else {
  1289. my $err = $!;
  1290. Log2Syslog_Log3slog($name, 3, "Log2Syslog $name - Warning - Payload sequence $pid NOT sent: $err\n");
  1291. $st = "write error: $err";
  1292. }
  1293. Log2Syslog_closesock($hash) if($st =~ /^write error:.*/);
  1294. }
  1295. }
  1296. my $evt = ($st eq $hash->{HELPER}{OLDSTATE})?0:1;
  1297. readingsSingleUpdate($hash, "state", $st, $evt);
  1298. $hash->{HELPER}{OLDSTATE} = $st;
  1299. return;
  1300. }
  1301. #################################################################################
  1302. # Test Message senden
  1303. #################################################################################
  1304. sub Log2Syslog_sendTestMsg($$) {
  1305. my ($hash,$own) = @_;
  1306. my $name = $hash->{NAME};
  1307. my $st = ReadingsVal($name,"state","active");
  1308. my ($prival,$ts,$sock,$tim,$date,$time,$err,$ret,$data,$pid,$otp);
  1309. if($own) {
  1310. # eigene Testmessage ohne Formatanpassung raw senden
  1311. $data = $own;
  1312. $pid = $hash->{SEQNO}; # PayloadID zur Nachverfolgung der Eventabfolge
  1313. $hash->{SEQNO}++;
  1314. } else {
  1315. $ts = TimeNow();
  1316. ($date,$time) = split(" ",$ts);
  1317. $date =~ s/\./-/g;
  1318. $tim = $date." ".$time;
  1319. $otp = "Test message from FHEM Syslog Client from ($hash->{MYHOST})";
  1320. $otp = "$tim $otp" if AttrVal($name,'addTimestamp',0);
  1321. $prival = "14";
  1322. ($data,$pid) = Log2Syslog_setpayload($hash,$prival,$date,$time,$otp,"fhem");
  1323. return if(!$data);
  1324. }
  1325. ($sock,$st) = Log2Syslog_opensock($hash,0);
  1326. if ($sock) {
  1327. $ret = syswrite $sock, $data."\n" if($data);
  1328. if($ret && $ret > 0) {
  1329. Log2Syslog_Log3slog($name, 4, "$name - Payload sequence $pid sent\n");
  1330. $st = "maintenance";
  1331. } else {
  1332. my $err = $!;
  1333. Log2Syslog_Log3slog($name, 3, "$name - Warning - Payload sequence $pid NOT sent: $err\n");
  1334. $st = "write error: $err";
  1335. }
  1336. Log2Syslog_closesock($hash) if($st =~ /^write error:.*/);
  1337. }
  1338. my $evt = ($st eq $hash->{HELPER}{OLDSTATE})?0:1;
  1339. readingsSingleUpdate($hash, "state", $st, $evt);
  1340. $hash->{HELPER}{OLDSTATE} = $st;
  1341. return;
  1342. }
  1343. ###############################################################################
  1344. # Helper für ident & Regex setzen
  1345. ###############################################################################
  1346. sub Log2Syslog_setidrex ($$) {
  1347. my ($hash,$a) = @_;
  1348. $hash->{HELPER}{EVNTLOG} = (split("event:",$a))[1] if(lc($a) =~ m/^event:.*/);
  1349. $hash->{HELPER}{FHEMLOG} = (split("fhem:",$a))[1] if(lc($a) =~ m/^fhem:.*/);
  1350. $hash->{HELPER}{IDENT} = (split("ident:",$a))[1] if(lc($a) =~ m/^ident:.*/);
  1351. return;
  1352. }
  1353. ###############################################################################
  1354. # Zeichencodierung für Payload filtern
  1355. ###############################################################################
  1356. sub Log2Syslog_charfilter ($$) {
  1357. my ($hash,$txt) = @_;
  1358. my $name = $hash->{NAME};
  1359. # nur erwünschte Zeichen in payload, ASCII %d32-126
  1360. $txt =~ s/ß/ss/g;
  1361. $txt =~ s/ä/ae/g;
  1362. $txt =~ s/ö/oe/g;
  1363. $txt =~ s/ü/ue/g;
  1364. $txt =~ s/Ä/Ae/g;
  1365. $txt =~ s/Ö/Oe/g;
  1366. $txt =~ s/Ü/Ue/g;
  1367. $txt =~ s/€/EUR/g;
  1368. $txt =~ tr/ A-Za-z0-9!"#$%&'()*+,-.\/:;<=>?@[\]^_`{|}~//cd;
  1369. return($txt);
  1370. }
  1371. ###############################################################################
  1372. # erstelle Socket
  1373. ###############################################################################
  1374. sub Log2Syslog_opensock ($;$$) {
  1375. my ($hash,$supresslog) = @_;
  1376. my $name = $hash->{NAME};
  1377. my $host = $hash->{PEERHOST};
  1378. my $port = AttrVal($name, "TLS", 0)?AttrVal($name, "port", 6514):AttrVal($name, "port", 514);
  1379. my $protocol = lc(AttrVal($name, "protocol", "udp"));
  1380. my $st = ReadingsVal($name,"state","active");
  1381. my $timeout = AttrVal($name, "timeout", 0.5);
  1382. my $ssldbg = AttrVal($name, "ssldebug", 0);
  1383. my ($sock,$lo,$lof,$sslver,$sslalgo);
  1384. return undef if($init_done != 1 || $hash->{MODEL} !~ /Sender/);
  1385. if($hash->{CLIENTSOCKET}) {
  1386. return($hash->{CLIENTSOCKET},$st);
  1387. }
  1388. Log2Syslog_Log3slog ($hash, 3, "Log2Syslog $name - Opening client socket on port \"$port\" ...") if(!$supresslog);
  1389. if(AttrVal($name, "TLS", 0)) {
  1390. # TLS gesicherte Verbindung
  1391. # TLS Transport nach RFC5425 https://tools.ietf.org/pdf/rfc5425.pdf
  1392. $attr{$name}{protocol} = "TCP" if(AttrVal($name, "protocol", "UDP") ne "TCP");
  1393. $sslver = "n.a.";
  1394. $sslalgo = "n.a.";
  1395. eval "use IO::Socket::SSL";
  1396. if($@) {
  1397. $st = "$@";
  1398. } else {
  1399. $sock = IO::Socket::INET->new(PeerHost => $host, PeerPort => $port, Proto => 'tcp', Blocking => 0);
  1400. if (!$sock) {
  1401. $st = "unable open socket for $host, $protocol, $port: $!";
  1402. } else {
  1403. $sock->blocking(1);
  1404. $IO::Socket::SSL::DEBUG = $ssldbg;
  1405. eval { IO::Socket::SSL->start_SSL($sock,
  1406. SSL_verify_mode => 0,
  1407. SSL_version => "TLSv1_2:!TLSv1_1:!SSLv3:!SSLv23:!SSLv2",
  1408. SSL_hostname => $host,
  1409. SSL_veriycn_scheme => "rfc5425",
  1410. SSL_veriycn_publicsuffix => '',
  1411. Timeout => $timeout
  1412. ) || undef $sock; };
  1413. $IO::Socket::SSL::DEBUG = 0;
  1414. if($@) {
  1415. $st = "SSL error: $@";
  1416. undef $sock;
  1417. } elsif (!$sock) {
  1418. $st = "SSL error: ".IO::Socket::SSL::errstr();
  1419. undef $sock;
  1420. } else {
  1421. $sslver = $sock->get_sslversion();
  1422. $sslalgo = $sock->get_fingerprint();
  1423. $sslalgo = (split("\\\$",$sslalgo))[0];
  1424. $lof = "Socket opened for Host: $host, Protocol: $protocol, Port: $port, TLS: 1";
  1425. $st = "active";
  1426. }
  1427. }
  1428. }
  1429. } else {
  1430. # erstellt ungesicherte Socket Verbindung
  1431. $sslver = "n.a.";
  1432. $sslalgo = "n.a.";
  1433. $sock = new IO::Socket::INET (PeerHost => $host, PeerPort => $port, Proto => $protocol, Timeout => $timeout );
  1434. if (!$sock) {
  1435. undef $sock;
  1436. $st = "unable open socket for $host, $protocol, $port: $!";
  1437. $lo = "Socket not opened: $!";
  1438. } else {
  1439. $sock->blocking(0);
  1440. $st = "active";
  1441. # Logausgabe (nur in das fhem Logfile !)
  1442. $lof = "Socket opened for Host: $host, Protocol: $protocol, Port: $port, TLS: 0";
  1443. }
  1444. }
  1445. if($sslver ne $hash->{HELPER}{SSLVER}) {
  1446. readingsSingleUpdate($hash, "SSL_Version", $sslver, 1);
  1447. $hash->{HELPER}{SSLVER} = $sslver;
  1448. }
  1449. if($sslalgo ne $hash->{HELPER}{SSLALGO}) {
  1450. readingsSingleUpdate($hash, "SSL_Algorithm", $sslalgo, 1);
  1451. $hash->{HELPER}{SSLALGO} = $sslalgo;
  1452. }
  1453. Log2Syslog_Log3slog($name, 3, "Log2Syslog $name - $lo") if($lo);
  1454. Log2Syslog_Log3slog($name, 3, "Log2Syslog $name - $lof") if($lof && !$supresslog && !$hash->{CLIENTSOCKET});
  1455. $hash->{CLIENTSOCKET} = $sock if($sock);
  1456. return($sock,$st);
  1457. }
  1458. ###############################################################################
  1459. # Socket schließen
  1460. ###############################################################################
  1461. sub Log2Syslog_closesock($;$$) {
  1462. my ($hash,$dolog) = @_;
  1463. my $name = $hash->{NAME};
  1464. my $st = "closed";
  1465. my $evt;
  1466. my $sock = $hash->{CLIENTSOCKET};
  1467. if($sock) {
  1468. Log2Syslog_Log3slog ($hash, 3, "Log2Syslog $name - Closing client socket ...") if($dolog);
  1469. shutdown($sock, 1);
  1470. if(AttrVal($hash->{NAME}, "TLS", 0) && ReadingsVal($name,"SSL_Algorithm", "n.a.") ne "n.a.") {
  1471. $sock->close(SSL_no_shutdown => 1);
  1472. $hash->{HELPER}{SSLVER} = "n.a.";
  1473. $hash->{HELPER}{SSLALGO} = "n.a.";
  1474. readingsSingleUpdate($hash, "SSL_Version", "n.a.", 1);
  1475. readingsSingleUpdate($hash, "SSL_Algorithm", "n.a.", 1);
  1476. } else {
  1477. $sock->close();
  1478. }
  1479. Log2Syslog_Log3slog ($hash, 3, "Log2Syslog $name - Client socket closed ...") if($dolog);
  1480. delete($hash->{CLIENTSOCKET});
  1481. if($dolog) {
  1482. $evt = ($st eq $hash->{HELPER}{OLDSTATE})?0:1;
  1483. readingsSingleUpdate($hash, "state", $st, $evt);
  1484. $hash->{HELPER}{OLDSTATE} = $st;
  1485. }
  1486. }
  1487. return;
  1488. }
  1489. ###############################################################################
  1490. # set PRIVAL (severity & facility)
  1491. ###############################################################################
  1492. sub Log2Syslog_setprival ($;$$) {
  1493. my ($txt,$vbose) = @_;
  1494. my ($prival,$sevAstxt);
  1495. # Priority = (facility * 8) + severity
  1496. # https://tools.ietf.org/pdf/rfc5424.pdf
  1497. # determine facility
  1498. my $fac = 5; # facility by syslogd
  1499. # calculate severity
  1500. # mapping verbose level to severity
  1501. # 0: Critical -> 2
  1502. # 1: Error -> 3
  1503. # 2: Warning -> 4
  1504. # 3: Notice -> 5
  1505. # 4: Informational -> 6
  1506. # 5: Debug -> 7
  1507. my $sv = 5; # notice (default)
  1508. if ($vbose) {
  1509. # map verbose to severity
  1510. $sv = 2 if ($vbose == 0);
  1511. $sv = 3 if ($vbose == 1);
  1512. $sv = 4 if ($vbose == 2);
  1513. $sv = 5 if ($vbose == 3);
  1514. $sv = 6 if ($vbose == 4);
  1515. $sv = 7 if ($vbose == 5);
  1516. }
  1517. $sv = 3 if (lc($txt) =~ m/error/); # error condition
  1518. $sv = 4 if (lc($txt) =~ m/warning/); # warning conditions
  1519. $prival = ($fac*8)+$sv;
  1520. $sevAstxt = $Log2Syslog_Severity{$sv};
  1521. return($prival,$sevAstxt);
  1522. }
  1523. ###############################################################################
  1524. # erstellen Payload für Syslog
  1525. ###############################################################################
  1526. sub Log2Syslog_setpayload ($$$$$$) {
  1527. my ($hash,$prival,$date,$time,$otp,$lt) = @_;
  1528. my $name = $hash->{NAME};
  1529. my $ident = ($hash->{HELPER}{IDENT}?$hash->{HELPER}{IDENT}:$name)."_".$lt;
  1530. my $myhost = $hash->{MYHOST}?$hash->{MYHOST}:"0.0.0.0";
  1531. my $myfqdn = $hash->{MYFQDN}?$hash->{MYFQDN}:$myhost;
  1532. my $lf = AttrVal($name, "logFormat", "IETF");
  1533. my $cdl = AttrVal($name, "contDelimiter", ""); # Trennzeichen vor Content (z.B. für Synology nötig)
  1534. my $data;
  1535. return undef,undef if(!$otp);
  1536. my $pid = $hash->{SEQNO}; # PayloadID zur Nachverfolgung der Eventabfolge
  1537. $hash->{SEQNO}++;
  1538. my ($year,$month,$day) = split("-",$date);
  1539. if ($lf eq "BSD") {
  1540. # BSD Protokollformat https://tools.ietf.org/html/rfc3164
  1541. $time = (split(/\./,$time))[0] if($time =~ m/\./); # msec ist nicht erlaubt
  1542. $month = $Log2Syslog_BSDMonth{$month}; # Monatsmapping, z.B. 01 -> Jan
  1543. $day =~ s/0/ / if($day =~ m/^0.*$/); # in Tagen < 10 muss 0 durch Space ersetzt werden
  1544. my $tag = substr($ident,0, $RFC3164len{TAG}); # Länge TAG Feld begrenzen
  1545. no warnings 'uninitialized';
  1546. $tag = $tag."[$pid]: ".$cdl; # TAG-Feld um PID und Content-Delimiter ergänzen
  1547. $data = "<$prival>$month $day $time $myhost $tag$otp";
  1548. use warnings;
  1549. $data = substr($data,0, ($RFC3164len{DL}-1)); # Länge Total begrenzen
  1550. }
  1551. if ($lf eq "IETF") {
  1552. # IETF Protokollformat https://tools.ietf.org/html/rfc5424
  1553. my $IETFver = 1; # Version von syslog Protokoll Spec RFC5424
  1554. my $mid = "FHEM"; # message ID, identify protocol of message, e.g. for firewall filter
  1555. my $tim = $date."T".$time;
  1556. my $sdfield = "[version\@Log2Syslog version=\"$hash->{VERSION}\"]";
  1557. $otp = Encode::encode_utf8($otp);
  1558. # Längenbegrenzung nach RFC5424
  1559. $ident = substr($ident,0, ($RFC5425len{ID}-1));
  1560. $pid = substr($pid,0, ($RFC5425len{PID}-1));
  1561. $mid = substr($mid,0, ($RFC5425len{MID}-1));
  1562. $myfqdn = substr($myfqdn,0, ($RFC5425len{HST}-1));
  1563. no warnings 'uninitialized';
  1564. if ($IETFver == 1) {
  1565. $data = "<$prival>$IETFver $tim $myfqdn $ident $pid $mid $sdfield $cdl$otp";
  1566. }
  1567. use warnings;
  1568. }
  1569. if($data =~ /\s$/) {$data =~ s/\s$//;}
  1570. $data = $data."\n";
  1571. my $dl = length($data); # Länge muss ! für TLS stimmen, sonst keine Ausgabe !
  1572. # wenn Transport Layer Security (TLS) -> Transport Mapping for Syslog https://tools.ietf.org/pdf/rfc5425.pdf
  1573. # oder Octet counting -> Transmission of Syslog Messages over TCP https://tools.ietf.org/html/rfc6587
  1574. if(AttrVal($name, "TLS", 0) || AttrVal($name, "octetCount", 0)) {
  1575. $data = "$dl $data";
  1576. Log2Syslog_Log3slog($name, 4, "$name - Payload created with octet count length: ".$dl);
  1577. }
  1578. my $ldat = ($dl>130)?(substr($data,0, 130)." ..."):$data;
  1579. Log2Syslog_Log3slog($name, 4, "$name - Payload sequence $pid created:\n$ldat");
  1580. return($data,$pid);
  1581. }
  1582. ###############################################################################
  1583. # eigene Log3-Ableitung - Schleife vermeiden
  1584. ###############################################################################
  1585. sub Log2Syslog_Log3slog($$$) {
  1586. my ($dev, $loglevel, $text) = @_;
  1587. our ($logopened,$currlogfile);
  1588. $dev = $dev->{NAME} if(defined($dev) && ref($dev) eq "HASH");
  1589. if(defined($dev) &&
  1590. defined($attr{$dev}) &&
  1591. defined (my $devlevel = $attr{$dev}{verbose})) {
  1592. return if($loglevel > $devlevel);
  1593. } else {
  1594. return if($loglevel > $attr{global}{verbose});
  1595. }
  1596. my ($seconds, $microseconds) = gettimeofday();
  1597. my @t = localtime($seconds);
  1598. my $nfile = ResolveDateWildcards($attr{global}{logfile}, @t);
  1599. OpenLogfile($nfile) if(!$currlogfile || $currlogfile ne $nfile);
  1600. my $tim = sprintf("%04d.%02d.%02d %02d:%02d:%02d",
  1601. $t[5]+1900,$t[4]+1,$t[3], $t[2],$t[1],$t[0]);
  1602. if($attr{global}{mseclog}) {
  1603. $tim .= sprintf(".%03d", $microseconds/1000);
  1604. }
  1605. if($logopened) {
  1606. print LOG "$tim $loglevel: $text\n";
  1607. } else {
  1608. print "$tim $loglevel: $text\n";
  1609. }
  1610. return undef;
  1611. }
  1612. ###############################################################################
  1613. # Bestimmung Übertragungsrate
  1614. ###############################################################################
  1615. sub Log2Syslog_trate($) {
  1616. my ($hash) = @_;
  1617. my $name = $hash->{NAME};
  1618. my $rerun = AttrVal($name, "rateCalcRerun", 60);
  1619. if ($hash->{HELPER}{LTIME}+60 <= time()) {
  1620. my $div = (time()-$hash->{HELPER}{LTIME})/60;
  1621. my $spm = sprintf "%.0f", ($hash->{SEQNO} - $hash->{HELPER}{OLDSEQNO})/$div;
  1622. $hash->{HELPER}{OLDSEQNO} = $hash->{SEQNO};
  1623. $hash->{HELPER}{LTIME} = time();
  1624. my $ospm = ReadingsVal($name, "Transfered_logs_per_minute", 0);
  1625. if($spm != $ospm) {
  1626. readingsSingleUpdate($hash, "Transfered_logs_per_minute", $spm, 1);
  1627. } else {
  1628. readingsSingleUpdate($hash, "Transfered_logs_per_minute", $spm, 0);
  1629. }
  1630. }
  1631. RemoveInternalTimer($hash, "Log2Syslog_trate");
  1632. InternalTimer(gettimeofday()+$rerun, "Log2Syslog_trate", $hash, 0);
  1633. return;
  1634. }
  1635. ###############################################################################
  1636. # Peer IP-Adresse und Host ermitteln (Sender der Message)
  1637. ###############################################################################
  1638. sub Log2Syslog_evalPeer($) {
  1639. my ($hash) = @_;
  1640. my $name = $hash->{NAME};
  1641. my $socket = $hash->{SERVERSOCKET};
  1642. my $protocol = lc(AttrVal($name, "protocol", "udp"));
  1643. if($hash->{TEMPORARY}) {
  1644. # temporäre Instanz abgelegt durch TcpServer_Accept
  1645. $protocol = "tcp";
  1646. }
  1647. my ($phost,$paddr,$pport, $pipaddr);
  1648. no warnings 'uninitialized';
  1649. if($protocol =~ /tcp/) {
  1650. $pipaddr = $hash->{HELPER}{TCPPADDR}; # gespeicherte IP-Adresse
  1651. $phost = $hash->{HIPCACHE}{$pipaddr}; # zuerst IP/Host-Kombination aus Cache nehmen falls vorhanden
  1652. if(!$phost) {
  1653. $paddr = inet_aton($pipaddr);
  1654. $phost = gethostbyaddr($paddr, AF_INET);
  1655. $hash->{HIPCACHE}{$pipaddr} = $phost if($phost);
  1656. }
  1657. } elsif ($protocol =~ /udp/ && $socket) {
  1658. # Protokoll UDP
  1659. ($pport, $paddr) = sockaddr_in($socket->peername) if($socket->peername);
  1660. $pipaddr = inet_ntoa($paddr) if($paddr);
  1661. $phost = $hash->{HIPCACHE}{$pipaddr}; # zuerst IP/Host-Kombination aus Cache nehmen falls vorhanden
  1662. if(!$phost) {
  1663. $phost = gethostbyaddr($paddr, AF_INET);
  1664. $hash->{HIPCACHE}{$pipaddr} = $phost if($phost);
  1665. }
  1666. }
  1667. Log2Syslog_Log3slog ($hash, 5, "Log2Syslog $name - message peer: $phost,$pipaddr");
  1668. use warnings;
  1669. $phost = $phost?$phost:$pipaddr?$pipaddr:"unknown";
  1670. return ($phost);
  1671. }
  1672. ###############################################################################
  1673. # Memory-Lock
  1674. # - solange gesetzt erfolgt keine Socketöffnung
  1675. # - löschen Sperre über Internaltimer
  1676. ###############################################################################
  1677. sub Log2Syslog_IsMemLock($) {
  1678. my ($hash) = @_;
  1679. my $ret = 0;
  1680. $ret = 1 if($hash->{HELPER}{MEMLOCK});
  1681. return ($ret);
  1682. }
  1683. sub Log2Syslog_deleteMemLock($) {
  1684. my ($hash) = @_;
  1685. RemoveInternalTimer($hash, "Log2Syslog_deleteMemLock");
  1686. delete($hash->{HELPER}{MEMLOCK});
  1687. return;
  1688. }
  1689. 1;
  1690. =pod
  1691. =item helper
  1692. =item summary forward FHEM system logs/events to a syslog server/act as an syslog server
  1693. =item summary_DE sendet FHEM Logs/Events an Syslog-Server / agiert als Syslog-Server
  1694. =begin html
  1695. <a name="Log2Syslog"></a>
  1696. <h3>Log2Syslog</h3>
  1697. <ul>
  1698. The module sends FHEM systemlog entries and/or FHEM events to an external syslog server or act itself as an Syslog-Server
  1699. to receive Syslog-messages of other Devices which are able to send Syslog. <br>
  1700. The syslog protocol has been implemented according the specifications of <a href="https://tools.ietf.org/html/rfc5424"> RFC5424 (IETF)</a>,
  1701. <a href="https://tools.ietf.org/html/rfc3164"> RFC3164 (BSD)</a> and the TLS transport protocol according to
  1702. <a href="https://tools.ietf.org/pdf/rfc5425.pdf"> RFC5425</a>. <br>
  1703. <br>
  1704. <b>Prerequisits</b>
  1705. <ul>
  1706. <br/>
  1707. The additional perl modules "IO::Socket::INET" and "IO::Socket::SSL" (if SSL is used) must be installed on your system. <br>
  1708. Install this package from cpan or, on Debian based installations, better by: <br><br>
  1709. <code>sudo apt-get install libio-socket-multicast-perl</code><br>
  1710. <code>sudo apt-get install libio-socket-ssl-perl</code><br><br>
  1711. </ul>
  1712. <br>
  1713. <a name="Log2Syslogdefine"></a>
  1714. <b>Definition and usage</b>
  1715. <ul>
  1716. <br>
  1717. Depending of the intended purpose a Syslog-Server (MODEL Collector) or a Syslog-Client (MODEL Sender) can be
  1718. defined. <br>
  1719. The Collector receives messages in Syslog-format of other Devices and hence generates Events/Readings for further
  1720. processing. The Sender-Device forwards FHEM Systemlog entries and/or Events to an external Syslog-Server. <br>
  1721. </ul>
  1722. <br>
  1723. <b><h4> The Collector (Syslog-Server) </h4></b>
  1724. <ul>
  1725. <b> Definition of a Collector </b>
  1726. <br>
  1727. <ul>
  1728. <br>
  1729. <code>define &lt;name&gt; Log2Syslog </code><br>
  1730. <br>
  1731. </ul>
  1732. The Definition don't need any further parameter.
  1733. In basic setup the Syslog-Server is initialized with Port=1514/UDP and the Parsingprofil "IETF".
  1734. By the <a href="#Log2Syslogattr">attribute</a> "parseProfile" another formats (e.g. BSD) can be selected.
  1735. The Syslog-Server is immediately ready for use, is parsing the Syslog-data accordingly the rules of RFC5424 and
  1736. generates FHEM-Events from received Syslog-messages (pls. see Eventmonitor for parsed data). <br><br>
  1737. <br>
  1738. <b>Example of a Collector: </b><br>
  1739. <ul>
  1740. <br>
  1741. <code>define SyslogServer Log2Syslog </code><br>
  1742. <br>
  1743. </ul>
  1744. The generated events are visible in the FHEM-Eventmonitor. <br>
  1745. <br>
  1746. Example of generated Events with attribute parseProfile=IETF: <br>
  1747. <br>
  1748. <code>
  1749. 2018-07-31 17:07:24.382 Log2Syslog SyslogServer HOST: fhem.myds.me || FAC: syslog || SEV: Notice || ID: Prod_event || CONT: USV state: OL <br>
  1750. 2018-07-31 17:07:24.858 Log2Syslog SyslogServer HOST: fhem.myds.me || FAC: syslog || SEV: Notice || ID: Prod_event || CONT: HMLAN2 loadLvl: low <br>
  1751. </code>
  1752. <br>
  1753. To separate fields the string "||" is used.
  1754. The meaning of the fields in the example is:
  1755. <br><br>
  1756. <ul>
  1757. <table>
  1758. <colgroup> <col width=20%> <col width=80%> </colgroup>
  1759. <tr><td> <b>HOST</b> </td><td> the Sender of the dataset </td></tr>
  1760. <tr><td> <b>FAC</b> </td><td> Facility corresponding to RFC5424 </td></tr>
  1761. <tr><td> <b>SEV</b> </td><td> Severity corresponding to RFC5424 </td></tr>
  1762. <tr><td> <b>ID</b> </td><td> Ident-Tag </td></tr>
  1763. <tr><td> <b>CONT</b> </td><td> the message part of the received message </td></tr>
  1764. </table>
  1765. </ul>
  1766. <br>
  1767. The timestamp of generated events is parsed from the Syslog-message. If this information isn't delivered, the current
  1768. timestamp of the operating system is used. <br>
  1769. The reading name in the generated event match the parsed hostname from Syslog-message.
  1770. If the message don't contain a hostname, the IP-address of the sender is retrieved from the network interface and
  1771. the hostname is determined if possible.
  1772. In this case the determined hostname respectively the IP-address is used as Reading in the generated event.
  1773. <br>
  1774. After definition of a Collectors Syslog-messages in IETF-format according to RFC5424 are expected. If the data are not
  1775. delivered in this record format and can't be parsed, the Reading "state" will contain the message
  1776. <b>"parse error - see logfile"</b> and the received Syslog-data are printed into the FHEM Logfile in raw-format. The
  1777. reading "Parse_Err_No" contains the number of parse-errors since module start.<br>
  1778. By the <a href="#Log2Syslogattr">attribute</a> "parseProfile" you can try to use another predefined parse-profile
  1779. or you can create an own parse-profile as well. <br><br>
  1780. To define an <b>own parse function</b> the
  1781. "parseProfile = ParseFn" has to be set and with <a href="#Log2Syslogattr">attribute</a> "parseFn" a specific
  1782. parse function has to be provided. <br>
  1783. The fields used by the event and their sequential arrangement can be selected from a range with
  1784. <a href="#Log2Syslogattr">attribute</a> "outputFields". Depending from the used parse-profil all or a subset of
  1785. the available fields can be selected. Further information about it you can find in description of attribute
  1786. "parseProfile". <br>
  1787. <br>
  1788. The behavior of the event generation can be adapted by <a href="#Log2Syslogattr">attribute</a> "makeEvent". <br>
  1789. </ul>
  1790. <br>
  1791. <b><h4> The Sender (Syslog-Client) </h4></b>
  1792. <ul>
  1793. <b> Definition of a Sender </b>
  1794. <br>
  1795. <ul>
  1796. <br>
  1797. <code>define &lt;name&gt; Log2Syslog &lt;destination host&gt; [ident:&lt;ident&gt;] [event:&lt;regexp&gt;] [fhem:&lt;regexp&gt;]</code><br>
  1798. <br>
  1799. </ul>
  1800. <ul>
  1801. <table>
  1802. <colgroup> <col width=25%> <col width=75%> </colgroup>
  1803. <tr><td> <b>&lt;destination host&gt;</b> </td><td> host (name or IP-address) where the syslog server is running </td></tr>
  1804. <tr><td> <b>[ident:&lt;ident&gt;]</b> </td><td> optional program identifier. If not set the device name will be used as default. </td></tr>
  1805. <tr><td> <b>[event:&lt;regexp&gt;]</b> </td><td> optional regex to filter events for logging </td></tr>
  1806. <tr><td> <b>[fhem:&lt;regexp&gt;]</b> </td><td> optional regex to filter fhem system log for logging </td></tr>
  1807. </table>
  1808. </ul>
  1809. <br><br>
  1810. After definition the new device sends all new appearing fhem systemlog entries and events to the destination host,
  1811. port=514/UDP format:IETF, immediately without further settings if the regex for fhem or event is set. <br>
  1812. Without setting a regex, no fhem system log or event log will be forwarded. <br><br>
  1813. The verbose level of FHEM system logs are converted into equivalent syslog severity level. <br>
  1814. Thurthermore the message text will be scanned for signal terms "warning" and "error" (with case insensitivity).
  1815. Dependent of it the severity will be set equivalent as well. If a severity is already set by verbose level, it will be
  1816. overwritten by the level according to the signal term found in the message text. <br><br>
  1817. <b>Lookup table Verbose-Level to Syslog severity level: </b><br><br>
  1818. <ul>
  1819. <table>
  1820. <colgroup> <col width=50%> <col width=50%> </colgroup>
  1821. <tr><td> <b>verbose-Level</b> </td><td> <b>Severity in Syslog</b> </td></tr>
  1822. <tr><td> 0 </td><td> Critical </td></tr>
  1823. <tr><td> 1 </td><td> Error </td></tr>
  1824. <tr><td> 2 </td><td> Warning </td></tr>
  1825. <tr><td> 3 </td><td> Notice </td></tr>
  1826. <tr><td> 4 </td><td> Informational </td></tr>
  1827. <tr><td> 5 </td><td> Debug </td></tr>
  1828. </table>
  1829. </ul>
  1830. <br>
  1831. <br>
  1832. <b>Example of a Sender: </b><br>
  1833. <ul>
  1834. <br>
  1835. <code>define splunklog Log2Syslog fhemtest 192.168.2.49 ident:Test event:.* fhem:.* </code><br/>
  1836. <br>
  1837. </ul>
  1838. All events are forwarded like this exmple of a raw-print of a Splunk Syslog Servers shows:<br/>
  1839. <pre>
  1840. Aug 18 21:06:46 fhemtest.myds.me 1 2017-08-18T21:06:46 fhemtest.myds.me Test_event 13339 FHEM [version@Log2Syslog version="4.2.0"] : LogDB sql_processing_time: 0.2306
  1841. Aug 18 21:06:46 fhemtest.myds.me 1 2017-08-18T21:06:46 fhemtest.myds.me Test_event 13339 FHEM [version@Log2Syslog version="4.2.0"] : LogDB background_processing_time: 0.2397
  1842. Aug 18 21:06:45 fhemtest.myds.me 1 2017-08-18T21:06:45 fhemtest.myds.me Test_event 13339 FHEM [version@Log2Syslog version="4.2.0"] : LogDB CacheUsage: 21
  1843. Aug 18 21:08:27 fhemtest.myds.me 1 2017-08-18T21:08:27.760 fhemtest.myds.me Test_fhem 13339 FHEM [version@Log2Syslog version="4.2.0"] : 4: CamTER - Informations of camera Terrasse retrieved
  1844. Aug 18 21:08:27 fhemtest.myds.me 1 2017-08-18T21:08:27.095 fhemtest.myds.me Test_fhem 13339 FHEM [version@Log2Syslog version="4.2.0"] : 4: CamTER - CAMID already set - ignore get camid
  1845. </pre>
  1846. The structure of the payload differs dependent of the used logFormat. <br><br>
  1847. <b>logFormat IETF:</b> <br><br>
  1848. "&lt;PRIVAL&gt;IETFVERS TIME MYHOST IDENT PID MID [SD-FIELD] MESSAGE" <br><br>
  1849. <ul>
  1850. <table>
  1851. <colgroup> <col width=10%> <col width=90%> </colgroup>
  1852. <tr><td> PRIVAL </td><td> priority value (coded from "facility" and "severity") </td></tr>
  1853. <tr><td> IETFVERS </td><td> used version of RFC5424 specification </td></tr>
  1854. <tr><td> TIME </td><td> timestamp according to RFC5424 </td></tr>
  1855. <tr><td> MYHOST </td><td> Internal MYHOST </td></tr>
  1856. <tr><td> IDENT </td><td> ident-Tag from DEF if set, or else the own device name. The statement will be completed by "_fhem" (FHEM-Log) respectively "_event" (Event-Log). </td></tr>
  1857. <tr><td> PID </td><td> sequential Payload-ID </td></tr>
  1858. <tr><td> MID </td><td> fix value "FHEM" </td></tr>
  1859. <tr><td> SD-FIELD </td><td> contains additional iformation about used module version </td></tr>
  1860. <tr><td> MESSAGE </td><td> the dataset to transfer </td></tr>
  1861. </table>
  1862. </ul>
  1863. <br>
  1864. <b>logFormat BSD:</b> <br><br>
  1865. "&lt;PRIVAL&gt;MONTH DAY TIME MYHOST IDENT[PID]: MESSAGE" <br><br>
  1866. <ul>
  1867. <table>
  1868. <colgroup> <col width=10%> <col width=90%> </colgroup>
  1869. <tr><td> PRIVAL </td><td> priority value (coded from "facility" and "severity") </td></tr>
  1870. <tr><td> MONTH </td><td> month according to RFC3164 </td></tr>
  1871. <tr><td> DAY </td><td> day of month according to RFC3164 </td></tr>
  1872. <tr><td> TIME </td><td> timestamp according to RFC3164 </td></tr>
  1873. <tr><td> MYHOST </td><td> Internal MYHOST </td></tr>
  1874. <tr><td> TAG </td><td> ident-Tag from DEF if set, or else the own device name. The statement will be completed by "_fhem" (FHEM-Log) respectively "_event" (Event-Log). </td></tr>
  1875. <tr><td> PID </td><td> the message-id (sequence number) </td></tr>
  1876. <tr><td> MESSAGE </td><td> the dataset to transfer </td></tr>
  1877. </table>
  1878. </ul>
  1879. <br>
  1880. </ul>
  1881. <br>
  1882. <a name="Log2SyslogSet"></a>
  1883. <b>Set</b>
  1884. <ul>
  1885. <br>
  1886. <ul>
  1887. <li><b>reopen </b><br>
  1888. <br>
  1889. Closes an existing Client/Server-connection and open it again.
  1890. This command can be helpful in case of e.g. "broken pipe"-errors.
  1891. </li>
  1892. </ul>
  1893. <br>
  1894. <ul>
  1895. <li><b>sendTestMessage [&lt;Message&gt;] </b><br>
  1896. <br>
  1897. With device type "Sender" a testmessage can be transfered. The format of the message depends on attribute "logFormat"
  1898. and contains data in BSD- or IETF-format.
  1899. Alternatively an own &lt;Message&gt; can be set. This message will be sent in im raw-format without
  1900. any conversion. The attribute "disable = maintenance" determines, that no data except test messages are sent
  1901. to the receiver.
  1902. </li>
  1903. </ul>
  1904. <br>
  1905. </ul>
  1906. <br>
  1907. <a name="Log2SyslogGet"></a>
  1908. <b>Get</b>
  1909. <ul>
  1910. <br>
  1911. <ul>
  1912. <li><b>certinfo </b><br>
  1913. <br>
  1914. On a SenderDevice the command shows informations about the server certificate in case a TLS-session was created
  1915. (Reading "SSL_Version" isn't "n.a.").
  1916. </li>
  1917. </ul>
  1918. <br>
  1919. <ul>
  1920. <li><b>versionNotes </b><br>
  1921. <br>
  1922. Shows release informations and hints about the module. Contains only main informations for module users.
  1923. </li>
  1924. </ul>
  1925. <br>
  1926. </ul>
  1927. <br>
  1928. <a name="Log2Syslogattr"></a>
  1929. <b>Attributes</b>
  1930. <ul>
  1931. <br>
  1932. <ul>
  1933. <a name="addTimestamp"></a>
  1934. <li><b>addTimestamp </b><br>
  1935. <br/>
  1936. The attribute is only usable for device type "Sender".
  1937. If set, FHEM timestamps will be logged too.<br>
  1938. Default behavior is not log these timestamps, because syslog uses own timestamps.<br>
  1939. Maybe useful if mseclog is activated in FHEM.<br>
  1940. <br>
  1941. Example output (raw) of a Splunk syslog server: <br>
  1942. <pre>Aug 18 21:26:55 fhemtest.myds.me 1 2017-08-18T21:26:55 fhemtest.myds.me Test_event 13339 FHEM - : 2017-08-18 21:26:55 USV state: OL
  1943. Aug 18 21:26:54 fhemtest.myds.me 1 2017-08-18T21:26:54 fhemtest.myds.me Test_event 13339 FHEM - : 2017-08-18 21:26:54 Bezug state: done
  1944. Aug 18 21:26:54 fhemtest.myds.me 1 2017-08-18T21:26:54 fhemtest.myds.me Test_event 13339 FHEM - : 2017-08-18 21:26:54 recalc_Bezug state: Next: 21:31:59
  1945. </pre>
  1946. </li>
  1947. </ul>
  1948. <br>
  1949. <ul>
  1950. <a name="addStateEvent"></a>
  1951. <li><b>addStateEvent </b><br>
  1952. <br>
  1953. The attribute is only usable for device type "Sender".
  1954. If set, events will be completed with "state" if a state-event appears. <br>
  1955. Default behavior is without getting "state".
  1956. </li>
  1957. </ul>
  1958. <br>
  1959. <br>
  1960. <ul>
  1961. <a name="contDelimiter"></a>
  1962. <li><b>contDelimiter </b><br>
  1963. <br>
  1964. The attribute is only usable for device type "Sender".
  1965. You can set an additional character which is straight inserted before the content-field. <br>
  1966. This possibility is useful in some special cases if the receiver need it (e.g. the Synology-Protokollcenter needs the
  1967. character ":" for proper function).
  1968. </li>
  1969. </ul>
  1970. <br>
  1971. <br>
  1972. <ul>
  1973. <a name="disable"></a>
  1974. <li><b>disable [1 | 0 | maintenance] </b><br>
  1975. <br>
  1976. This device will be activated, deactivated respectSeverity set into the maintenance-mode.
  1977. In maintenance-mode a test message can be sent by the "Sender"-device (pls. see also command "set &lt;name&gt;
  1978. sendTestMessage").
  1979. </li>
  1980. </ul>
  1981. <br>
  1982. <br>
  1983. <ul>
  1984. <a name="logFormat"></a>
  1985. <li><b>logFormat [ BSD | IETF ]</b><br>
  1986. <br>
  1987. This attribute is only usable for device type "Sender".
  1988. Set the syslog protocol format. <br>
  1989. Default value is "IETF" if not specified.
  1990. </li>
  1991. </ul>
  1992. <br>
  1993. <br>
  1994. <ul>
  1995. <a name="makeEvent"></a>
  1996. <li><b>makeEvent [ intern | no | reading ]</b><br>
  1997. <br>
  1998. The attribute is only usable for device type "Collector".
  1999. With this attribute the behavior of the event- and reading generation is defined.
  2000. <br><br>
  2001. <ul>
  2002. <table>
  2003. <colgroup> <col width=10%> <col width=90%> </colgroup>
  2004. <tr><td> <b>intern</b> </td><td> events are generated by module intern mechanism and only visible in FHEM eventmonitor. Readings are not created. </td></tr>
  2005. <tr><td> <b>no</b> </td><td> only readings like "MSG_&lt;hostname&gt;" without event generation are created </td></tr>
  2006. <tr><td> <b>reading</b> </td><td> readings like "MSG_&lt;hostname&gt;" are created. Events are created dependent of the "event-on-.*"-attributes </td></tr>
  2007. </table>
  2008. </ul>
  2009. </li>
  2010. </ul>
  2011. <br>
  2012. <br>
  2013. <ul>
  2014. <a name="octetCount"></a>
  2015. <li><b>octetCount </b><br>
  2016. <br>
  2017. The attribute is only usable for device type "Sender". <br>
  2018. If set, the Syslog Framing is changed from Non-Transparent-Framing (default) to Octet-Framing.
  2019. The Syslog-Reciver must support Octet-Framing !
  2020. For further informations see RFC6587 <a href="https://tools.ietf.org/html/rfc6587">"Transmission of Syslog Messages
  2021. over TCP"</a>.
  2022. </li>
  2023. </ul>
  2024. <br>
  2025. <br>
  2026. <ul>
  2027. <a name="outputFields"></a>
  2028. <li><b>outputFields </b><br>
  2029. <br>
  2030. The attribute is only usable for device type "Collector".
  2031. By a sortable list the desired fields of generated events can be selected.
  2032. The meaningful usable fields are depending on the attribute <b>"parseProfil"</b>. Their meaning can be found in
  2033. the description of attribute "parseProfil".
  2034. Is "outputFields" not defined, a predefined set of fields for event generation is used.
  2035. </li>
  2036. </ul>
  2037. <br>
  2038. <br>
  2039. <ul>
  2040. <a name="parseFn"></a>
  2041. <li><b>parseFn {&lt;Parsefunktion&gt;} </b><br>
  2042. <br>
  2043. The attribute is only usable for device type "Collector".
  2044. The provided perl function (has to be set into "{}") will be applied to the received Syslog-message.
  2045. The following variables are commited to the function. They can be used for programming, processing and for
  2046. value return. Variables which are provided as blank, are marked as "". <br>
  2047. In case of restrictions the expected format of variables return is specified in "()".
  2048. Otherwise the variable is usable for free.
  2049. <br><br>
  2050. <ul>
  2051. <table>
  2052. <colgroup> <col width=20%> <col width=80%> </colgroup>
  2053. <tr><td> $PRIVAL </td><td> "" (0 ... 191) </td></tr>
  2054. <tr><td> $FAC </td><td> "" (0 ... 23) </td></tr>
  2055. <tr><td> $SEV </td><td> "" (0 ... 7) </td></tr>
  2056. <tr><td> $TS </td><td> Timestamp (YYYY-MM-DD hh:mm:ss) </td></tr>
  2057. <tr><td> $HOST </td><td> "" </td></tr>
  2058. <tr><td> $DATE </td><td> "" (YYYY-MM-DD) </td></tr>
  2059. <tr><td> $TIME </td><td> "" (hh:mm:ss) </td></tr>
  2060. <tr><td> $ID </td><td> "" </td></tr>
  2061. <tr><td> $PID </td><td> "" </td></tr>
  2062. <tr><td> $MID </td><td> "" </td></tr>
  2063. <tr><td> $SDFIELD </td><td> "" </td></tr>
  2064. <tr><td> $CONT </td><td> "" </td></tr>
  2065. <tr><td> $DATA </td><td> provided raw-data of received Syslog-message (no evaluation of value return!) </td></tr>
  2066. <tr><td> $IGNORE </td><td> 0 (0|1), if $IGNORE==1 the Syslog-dataset is ignored </td></tr>
  2067. </table>
  2068. </ul>
  2069. <br>
  2070. The names of the variables corresponding to the field names and their primary meaning denoted in attribute
  2071. <b>"parseProfile"</b> (explanation of the field data). <br><br>
  2072. <ul>
  2073. <b>Example: </b> <br>
  2074. # Source text: '<4> <;4>LAN IP and mask changed to 192.168.2.3 255.255.255.0' <br>
  2075. # Task: The characters '<;4>' are to removed from the CONT-field
  2076. <pre>
  2077. {
  2078. ($PRIVAL,$CONT) = ($DATA =~ /^<(\d{1,3})>\s(.*)$/);
  2079. $CONT = (split(">",$CONT))[1] if($CONT =~ /^<.*>.*$/);
  2080. }
  2081. </pre>
  2082. </ul>
  2083. </li>
  2084. </ul>
  2085. <br>
  2086. <br>
  2087. <ul>
  2088. <a name="parseProfile"></a>
  2089. <li><b>parseProfile [ BSD | IETF | ... | ParseFn | raw ] </b><br>
  2090. <br>
  2091. Selection of a parse profile. The attribute is only usable for device type "Collector".
  2092. <br><br>
  2093. <ul>
  2094. <table>
  2095. <colgroup> <col width=20%> <col width=80%> </colgroup>
  2096. <tr><td> <b>BSD</b> </td><td> Parsing of messages in BSD-format according to RFC3164 </td></tr>
  2097. <tr><td> <b>IETF</b> </td><td> Parsing of messages in IETF-format according to RFC5424 (default) </td></tr>
  2098. <tr><td> <b>...</b> </td><td> further specific parse profiles for selective device are provided </td></tr>
  2099. <tr><td> <b>ParseFn</b> </td><td> Usage of an own specific parse function provided by attribute "parseFn" </td></tr>
  2100. <tr><td> <b>raw</b> </td><td> no parsing, events are created from the messages as received without conversion </td></tr>
  2101. </table>
  2102. </ul>
  2103. <br>
  2104. The parsed data are provided in fields. The fields to use for events and their sequence can be defined by
  2105. attribute <b>"outputFields"</b>. <br>
  2106. Dependent from used "parseProfile" the following fields are filled with values and therefor it is meaningful
  2107. to use only the namend fields by attribute "outputFields". By the "raw"-profil the received data are not converted
  2108. and the event is created directly.
  2109. <br><br>
  2110. The meaningful usable fields in attribute "outputFields" depending of the particular profil:
  2111. <br>
  2112. <br>
  2113. <ul>
  2114. <table>
  2115. <colgroup> <col width=10%> <col width=90%> </colgroup>
  2116. <tr><td> BSD </td><td>-> PRIVAL,FAC,SEV,TS,HOST,ID,CONT </td></tr>
  2117. <tr><td> IETF </td><td>-> PRIVAL,FAC,SEV,TS,HOST,DATE,TIME,ID,PID,MID,SDFIELD,CONT </td></tr>
  2118. <tr><td> ParseFn </td><td>-> PRIVAL,FAC,SEV,TS,HOST,DATE,TIME,ID,PID,MID,SDFIELD,CONT </td></tr>
  2119. <tr><td> raw </td><td>-> no selection is meaningful, the original message is used for event creation </td></tr>
  2120. </table>
  2121. </ul>
  2122. <br>
  2123. Explanation of field data:
  2124. <br>
  2125. <br>
  2126. <ul>
  2127. <table>
  2128. <colgroup> <col width=20%> <col width=80%> </colgroup>
  2129. <tr><td> PRIVAL </td><td> coded Priority value (coded from "facility" and "severity") </td></tr>
  2130. <tr><td> FAC </td><td> decoded Facility </td></tr>
  2131. <tr><td> SEV </td><td> decoded Severity of message </td></tr>
  2132. <tr><td> TS </td><td> Timestamp containing date and time (YYYY-MM-DD hh:mm:ss) </td></tr>
  2133. <tr><td> HOST </td><td> Hostname / Ip-address of the Sender </td></tr>
  2134. <tr><td> DATE </td><td> Date (YYYY-MM-DD) </td></tr>
  2135. <tr><td> TIME </td><td> Time (hh:mm:ss) </td></tr>
  2136. <tr><td> ID </td><td> Device or application what was sending the Syslog-message </td></tr>
  2137. <tr><td> PID </td><td> Programm-ID, offen reserved by process name or prozess-ID </td></tr>
  2138. <tr><td> MID </td><td> Type of message (arbitrary string) </td></tr>
  2139. <tr><td> SDFIELD </td><td> Metadaten about the received Syslog-message </td></tr>
  2140. <tr><td> CONT </td><td> Content of the message </td></tr>
  2141. <tr><td> DATA </td><td> received raw-data </td></tr>
  2142. </table>
  2143. </ul>
  2144. <br>
  2145. </li>
  2146. </ul>
  2147. <br>
  2148. <br>
  2149. <ul>
  2150. <a name="port"></a>
  2151. <li><b>port &lt;Port&gt;</b><br>
  2152. <br>
  2153. The used port. For a Sender the default-port is 514.
  2154. A Collector (Syslog-Server) uses the port 1514 per default.
  2155. </li>
  2156. </ul>
  2157. <br>
  2158. <br>
  2159. <ul>
  2160. <a name="protocol"></a>
  2161. <li><b>protocol [ TCP | UDP ]</b><br>
  2162. <br>
  2163. Sets the socket protocol which should be used. You can choose UDP or TCP. <br>
  2164. Default value is "UDP" if not specified.
  2165. </li>
  2166. </ul>
  2167. <br>
  2168. <br>
  2169. <ul>
  2170. <a name="rateCalcRerun"></a>
  2171. <li><b>rateCalcRerun &lt;Zeit in Sekunden&gt; </b><br>
  2172. <br>
  2173. Rerun cycle for calculation of log transfer rate (Reading "Transfered_logs_per_minute") in seconds (>=60).
  2174. Values less than 60 seconds are corrected to 60 seconds automatically.
  2175. Default is 60 seconds.
  2176. </li>
  2177. </ul>
  2178. <br>
  2179. <br>
  2180. <ul>
  2181. <a name="respectSeverity"></a>
  2182. <li><b>respectSeverity </b><br>
  2183. <br>
  2184. Messages are only forwarded (Sender) respectively the receipt considered (Collector), whose severity is included
  2185. by this attribute.
  2186. If "respectSeverity" isn't set, messages of all severity is processed.
  2187. </li>
  2188. </ul>
  2189. <br>
  2190. <br>
  2191. <ul>
  2192. <a name="sslCertPrefix"></a>
  2193. <li><b>sslCertPrefix</b><br>
  2194. <br>
  2195. Set the prefix for the SSL certificate, default is "certs/server-".
  2196. Setting this attribute you are able to specify different SSL-certificates for different Log2Syslog devices.
  2197. See also the TLS attribute.
  2198. </li>
  2199. </ul>
  2200. <br>
  2201. <br>
  2202. <ul>
  2203. <a name="ssldebug"></a>
  2204. <li><b>ssldebug</b><br>
  2205. <br>
  2206. Debugging level of SSL messages. The attribute is only usable for device type "Sender". <br><br>
  2207. <ul>
  2208. <li> 0 - No debugging (default). </li>
  2209. <li> 1 - Print out errors from <a href="http://search.cpan.org/~sullr/IO-Socket-SSL-2.056/lib/IO/Socket/SSL.pod">IO::Socket::SSL</a> and ciphers from <a href="http://search.cpan.org/~mikem/Net-SSLeay-1.85/lib/Net/SSLeay.pod">Net::SSLeay</a>. </li>
  2210. <li> 2 - Print also information about call flow from <a href="http://search.cpan.org/~sullr/IO-Socket-SSL-2.056/lib/IO/Socket/SSL.pod">IO::Socket::SSL</a> and progress information from <a href="http://search.cpan.org/~mikem/Net-SSLeay-1.85/lib/Net/SSLeay.pod">Net::SSLeay</a>. </li>
  2211. <li> 3 - Print also some data dumps from <a href="http://search.cpan.org/~sullr/IO-Socket-SSL-2.056/lib/IO/Socket/SSL.pod">IO::Socket::SSL</a> and from <a href="http://search.cpan.org/~mikem/Net-SSLeay-1.85/lib/Net/SSLeay.pod">Net::SSLeay</a>. </li>
  2212. </ul>
  2213. </li>
  2214. </ul>
  2215. <br>
  2216. <br>
  2217. <ul>
  2218. <a name="TLS"></a>
  2219. <li><b>TLS</b><br>
  2220. <br>
  2221. A client (Sender) establish a secured connection to a Syslog-Server.
  2222. A Syslog-Server (Collector) provide to establish a secured connection.
  2223. The protocol will be switched to TCP automatically.
  2224. <br<br>
  2225. Thereby a Collector device can use TLS, a certificate has to be created or available.
  2226. With following steps a certicate can be created: <br><br>
  2227. 1. in the FHEM basis directory create the directory "certs": <br>
  2228. <pre>
  2229. sudo mkdir /opt/fhem/certs
  2230. </pre>
  2231. 2. create the SSL certicate: <br>
  2232. <pre>
  2233. cd /opt/fhem/certs
  2234. sudo openssl req -new -x509 -nodes -out server-cert.pem -days 3650 -keyout server-key.pem
  2235. </pre>
  2236. 3. set file/directory permissions: <br>
  2237. <pre>
  2238. sudo chown -R fhem:dialout /opt/fhem/certs
  2239. sudo chmod 644 /opt/fhem/certs/*.pem
  2240. sudo chmod 711 /opt/fhem/certs
  2241. </pre>
  2242. </li>
  2243. </ul>
  2244. <br>
  2245. <br>
  2246. <ul>
  2247. <a name="timeout"></a>
  2248. <li><b>timeout</b><br>
  2249. <br>
  2250. This attribute is only usable for device type "Sender".
  2251. Timeout für die Verbindung zum Syslog-Server (TCP). Default: 0.5s.
  2252. </li>
  2253. </ul>
  2254. <br>
  2255. <br>
  2256. <ul>
  2257. <a name="verbose"></a>
  2258. <li><b>verbose</b><br>
  2259. <br>
  2260. Please see global <a href="#attributes">attribute</a> "verbose".
  2261. To avoid loops, the output of verbose level of the Log2Syslog-Devices will only be reported into the local FHEM
  2262. Logfile and not forwarded.
  2263. </li>
  2264. </ul>
  2265. <br>
  2266. <br>
  2267. </ul>
  2268. <br>
  2269. <a name="Log2Syslogreadings"></a>
  2270. <b>Readings</b>
  2271. <ul>
  2272. <br>
  2273. <table>
  2274. <colgroup> <col width=35%> <col width=65%> </colgroup>
  2275. <tr><td><b>MSG_&lt;Host&gt;</b> </td><td> the last successful parsed Syslog-message from &lt;Host&gt; </td></tr>
  2276. <tr><td><b>Parse_Err_No</b> </td><td> the number of parse errors since start </td></tr>
  2277. <tr><td><b>SSL_Algorithm</b> </td><td> used SSL algorithm if SSL is enabled and active </td></tr>
  2278. <tr><td><b>SSL_Version</b> </td><td> the used TLS-version if encryption is enabled and is active</td></tr>
  2279. <tr><td><b>Transfered_logs_per_minute</b> </td><td> the average number of forwarded logs/events per minute </td></tr>
  2280. </table>
  2281. <br>
  2282. </ul>
  2283. </ul>
  2284. =end html
  2285. =begin html_DE
  2286. <a name="Log2Syslog"></a>
  2287. <h3>Log2Syslog</h3>
  2288. <ul>
  2289. Das Modul sendet FHEM Systemlog-Einträge und/oder Events an einen externen Syslog-Server weiter oder agiert als
  2290. Syslog-Server um Syslog-Meldungen anderer Geräte zu empfangen. <br>
  2291. Die Implementierung des Syslog-Protokolls erfolgte entsprechend den Vorgaben von <a href="https://tools.ietf.org/html/rfc5424"> RFC5424 (IETF)</a>,
  2292. <a href="https://tools.ietf.org/html/rfc3164"> RFC3164 (BSD)</a> sowie dem TLS Transport Protokoll nach
  2293. <a href="https://tools.ietf.org/pdf/rfc5425.pdf"> RFC5425</a>. <br>
  2294. <br>
  2295. <b>Voraussetzungen</b>
  2296. <ul>
  2297. <br/>
  2298. Es werden die Perl Module "IO::Socket::INET" und "IO::Socket::SSL" (wenn SSL benutzt) benötigt und müssen installiert sein. <br>
  2299. Das Modul kann über CPAN oder, auf Debian Linux Systemen, besser mit <br><br>
  2300. <code>sudo apt-get install libio-socket-multicast-perl</code><br>
  2301. <code>sudo apt-get install libio-socket-ssl-perl</code><br><br>
  2302. installiert werden.
  2303. </ul>
  2304. <br/>
  2305. <a name="Log2Syslogdefine"></a>
  2306. <b>Definition und Verwendung</b>
  2307. <ul>
  2308. <br>
  2309. Je nach Verwendungszweck kann ein Syslog-Server (MODEL Collector) oder ein Syslog-Client (MODEL Sender) definiert
  2310. werden. <br>
  2311. Der Collector empfängt Meldungen im Syslog-Format anderer Geräte und generiert daraus Events/Readings zur Weiterverarbeitung in
  2312. FHEM. Das Sender-Device leitet FHEM Systemlog Einträge und/oder Events an einen externen Syslog-Server weiter. <br>
  2313. </ul>
  2314. <br>
  2315. <b><h4> Der Collector (Syslog-Server) </h4></b>
  2316. <ul>
  2317. <b> Definition eines Collectors </b>
  2318. <br>
  2319. <ul>
  2320. <br>
  2321. <code>define &lt;name&gt; Log2Syslog </code><br>
  2322. <br>
  2323. </ul>
  2324. Die Definition benötigt keine weiteren Parameter.
  2325. In der Grundeinstellung wird der Syslog-Server mit dem Port=1514/UDP und dem Parsingprofil "IETF" initialisiert.
  2326. Mit dem <a href="#Log2Syslogattr">Attribut</a> "parseProfile" können alternativ andere Formate (z.B. BSD) ausgewählt werden.
  2327. Der Syslog-Server ist sofort betriebsbereit, parst die Syslog-Daten entsprechend der Richtlinien nach RFC5424 und generiert
  2328. aus den eingehenden Syslog-Meldungen FHEM-Events (Daten sind im Eventmonitor sichtbar). <br><br>
  2329. <br>
  2330. <b>Beispiel für einen Collector: </b><br>
  2331. <ul>
  2332. <br>
  2333. <code>define SyslogServer Log2Syslog </code><br>
  2334. <br>
  2335. </ul>
  2336. Im Eventmonitor können die generierten Events kontrolliert werden. <br>
  2337. <br>
  2338. Beispiel von generierten Events mit Attribut parseProfile=IETF: <br>
  2339. <br>
  2340. <code>
  2341. 2018-07-31 17:07:24.382 Log2Syslog SyslogServer HOST: fhem.myds.me || FAC: syslog || SEV: Notice || ID: Prod_event || CONT: USV state: OL <br>
  2342. 2018-07-31 17:07:24.858 Log2Syslog SyslogServer HOST: fhem.myds.me || FAC: syslog || SEV: Notice || ID: Prod_event || CONT: HMLAN2 loadLvl: low <br>
  2343. </code>
  2344. <br>
  2345. Zwischen den einzelnen Feldern wird der Trenner "||" verwendet.
  2346. Die Bedeutung der Felder in diesem Beispiel sind:
  2347. <br><br>
  2348. <ul>
  2349. <table>
  2350. <colgroup> <col width=20%> <col width=80%> </colgroup>
  2351. <tr><td> <b>HOST</b> </td><td> der Sender des Datensatzes </td></tr>
  2352. <tr><td> <b>FAC</b> </td><td> Facility (Kategorie) nach RFC5424 </td></tr>
  2353. <tr><td> <b>SEV</b> </td><td> Severity (Schweregrad) nach RFC5424 </td></tr>
  2354. <tr><td> <b>ID</b> </td><td> Ident-Tag </td></tr>
  2355. <tr><td> <b>CONT</b> </td><td> der Nachrichtenteil der empfangenen Meldung </td></tr>
  2356. </table>
  2357. </ul>
  2358. <br>
  2359. Der Timestamp der generierten Events wird aus den Syslogmeldungen geparst. Sollte diese Information nicht mitgeliefert
  2360. werden, wird der aktuelle Timestamp des Systems verwendet. <br>
  2361. Der Name des Readings im generierten Event entspricht dem aus der Syslogmeldung geparsten Hostnamen.
  2362. Ist der Hostname in der Meldung nicht enthalten, wird die IP-Adresse des Senders aus dem Netzwerk Interface abgerufen und
  2363. der Hostname ermittelt sofern möglich.
  2364. In diesem Fall wird der ermittelte Hostname bzw. die IP-Adresse als Reading im Event genutzt.
  2365. <br>
  2366. Nach der Definition des Collectors werden die Syslog-Meldungen im IETF-Format gemäß RFC5424 erwartet. Werden die Daten
  2367. nicht in diesem Format geliefert bzw. können nicht geparst werden, erscheint im Reading "state" die Meldung
  2368. <b>"parse error - see logfile"</b> und die empfangenen Syslog-Daten werden im Logfile im raw-Format ausgegeben. Das Reading
  2369. "Parse_Err_No" enthält die Anzahl der Parse-Fehler seit Modulstart. <br>
  2370. In diesem Fall kann mit dem <a href="#Log2Syslogattr">Attribut</a> "parseProfile" ein anderes vordefiniertes Parse-Profil
  2371. eingestellt bzw. ein eigenes Profil definiert werden. <br><br>
  2372. Zur Definition einer <b>eigenen Parse-Funktion</b> wird
  2373. "parseProfile = ParseFn" eingestellt und im <a href="#Log2Syslogattr">Attribut</a> "parseFn" eine spezifische
  2374. Parse-Funktion hinterlegt. <br>
  2375. Die im Event verwendeten Felder und deren Reihenfolge können aus einem Wertevorrat mit dem
  2376. <a href="#Log2Syslogattr">Attribut</a> "outputFields" bestimmt werden. Je nach verwendeten Parse-Funktion können alle oder
  2377. nur eine Untermenge der verfügbaren Felder verwendet werden. Näheres dazu in der Beschreibung des Attributes "parseProfile". <br>
  2378. <br>
  2379. Das Verhalten der Eventgenerierung kann mit dem <a href="#Log2Syslogattr">Attribut</a> "makeEvent" angepasst werden. <br>
  2380. </ul>
  2381. <br>
  2382. <b><h4> Der Sender (Syslog-Client) </h4></b>
  2383. <ul>
  2384. <b> Definition eines Senders </b>
  2385. <br>
  2386. <ul>
  2387. <br>
  2388. <code>define &lt;name&gt; Log2Syslog &lt;Zielhost&gt; [ident:&lt;ident&gt;] [event:&lt;regexp&gt;] [fhem:&lt;regexp&gt;] </code><br>
  2389. <br>
  2390. </ul>
  2391. <ul>
  2392. <table>
  2393. <colgroup> <col width=20%> <col width=80%> </colgroup>
  2394. <tr><td> <b>&lt;Zielhost&gt;</b> </td><td> Host (Name oder IP-Adresse) auf dem der Syslog-Server läuft </td></tr>
  2395. <tr><td> <b>[ident:&lt;ident&gt;]</b> </td><td> optionaler Programm Identifier. Wenn nicht gesetzt wird per default der Devicename benutzt. </td></tr>
  2396. <tr><td> <b>[event:&lt;regexp&gt;]</b> </td><td> optionaler regulärer Ausdruck zur Filterung von Events zur Weiterleitung </td></tr>
  2397. <tr><td> <b>[fhem:&lt;regexp&gt;]</b> </td><td> optionaler regulärer Ausdruck zur Filterung von FHEM Logs zur Weiterleitung </td></tr>
  2398. </table>
  2399. </ul>
  2400. <br><br>
  2401. Direkt nach der Definition sendet das neue Device alle neu auftretenden FHEM Systemlog Einträge und Events ohne weitere
  2402. Einstellungen an den Zielhost, Port=514/UDP Format=IETF, wenn reguläre Ausdrücke für Events/FHEM angegeben wurden. <br>
  2403. Wurde kein Regex gesetzt, erfolgt keine Weiterleitung von Events oder FHEM Systemlogs. <br><br>
  2404. Die Verbose-Level der FHEM Systemlogs werden in entsprechende Schweregrade der Syslog-Messages umgewandelt. <br>
  2405. Weiterhin wird der Meldungstext der FHEM Systemlogs und Events nach den Signalwörtern "warning" und "error" durchsucht
  2406. (Groß- /Kleinschreibung wird nicht beachtet). Davon abhängig wird der Schweregrad ebenfalls äquivalent gesetzt und übersteuert
  2407. einen eventuell bereits durch Verbose-Level gesetzten Schweregrad. <br><br>
  2408. <b>Umsetzungstabelle Verbose-Level in Syslog-Schweregrad Stufe: </b><br><br>
  2409. <ul>
  2410. <table>
  2411. <colgroup> <col width=40%> <col width=60%> </colgroup>
  2412. <tr><td> <b>Verbose-Level</b> </td><td> <b>Schweregrad in Syslog</b> </td></tr>
  2413. <tr><td> 0 </td><td> Critical </td></tr>
  2414. <tr><td> 1 </td><td> Error </td></tr>
  2415. <tr><td> 2 </td><td> Warning </td></tr>
  2416. <tr><td> 3 </td><td> Notice </td></tr>
  2417. <tr><td> 4 </td><td> Informational </td></tr>
  2418. <tr><td> 5 </td><td> Debug </td></tr>
  2419. </table>
  2420. </ul>
  2421. <br>
  2422. <br>
  2423. <b>Beispiel für einen Sender: </b><br>
  2424. <ul>
  2425. <br>
  2426. <code>define splunklog Log2Syslog fhemtest 192.168.2.49 ident:Test event:.* fhem:.* </code><br/>
  2427. <br>
  2428. </ul>
  2429. Es werden alle Events weitergeleitet wie deses Beispiel der raw-Ausgabe eines Splunk Syslog Servers zeigt:<br/>
  2430. <pre>
  2431. Aug 18 21:06:46 fhemtest.myds.me 1 2017-08-18T21:06:46 fhemtest.myds.me Test_event 13339 FHEM [version@Log2Syslog version="4.2.0"] : LogDB sql_processing_time: 0.2306
  2432. Aug 18 21:06:46 fhemtest.myds.me 1 2017-08-18T21:06:46 fhemtest.myds.me Test_event 13339 FHEM [version@Log2Syslog version="4.2.0"] : LogDB background_processing_time: 0.2397
  2433. Aug 18 21:06:45 fhemtest.myds.me 1 2017-08-18T21:06:45 fhemtest.myds.me Test_event 13339 FHEM [version@Log2Syslog version="4.2.0"] : LogDB CacheUsage: 21
  2434. Aug 18 21:08:27 fhemtest.myds.me 1 2017-08-18T21:08:27.760 fhemtest.myds.me Test_fhem 13339 FHEM [version@Log2Syslog version="4.2.0"] : 4: CamTER - Informations of camera Terrasse retrieved
  2435. Aug 18 21:08:27 fhemtest.myds.me 1 2017-08-18T21:08:27.095 fhemtest.myds.me Test_fhem 13339 FHEM [version@Log2Syslog version="4.2.0"] : 4: CamTER - CAMID already set - ignore get camid
  2436. </pre>
  2437. Der Aufbau der Payload unterscheidet sich je nach verwendeten logFormat. <br><br>
  2438. <b>logFormat IETF:</b> <br><br>
  2439. "&lt;PRIVAL&gt;IETFVERS TIME MYHOST IDENT PID MID [SD-FIELD] MESSAGE" <br><br>
  2440. <ul>
  2441. <table>
  2442. <colgroup> <col width=10%> <col width=90%> </colgroup>
  2443. <tr><td> PRIVAL </td><td> Priority Wert (kodiert aus "facility" und "severity") </td></tr>
  2444. <tr><td> IETFVERS </td><td> Version der benutzten RFC5424 Spezifikation </td></tr>
  2445. <tr><td> TIME </td><td> Timestamp nach RFC5424 </td></tr>
  2446. <tr><td> MYHOST </td><td> Internal MYHOST </td></tr>
  2447. <tr><td> IDENT </td><td> Ident-Tag aus DEF wenn angegeben, sonst der eigene Devicename. Die Angabe wird mit "_fhem" (FHEM-Log) bzw. "_event" (Event-Log) ergänzt. </td></tr>
  2448. <tr><td> PID </td><td> fortlaufende Payload-ID </td></tr>
  2449. <tr><td> MID </td><td> fester Wert "FHEM" </td></tr>
  2450. <tr><td> [SD-FIELD] </td><td> Structured Data Feld. Enthält Informationen zur verwendeten Modulversion (die Klammern "[]" sind Bestandteil des Feldes)</td></tr>
  2451. <tr><td> MESSAGE </td><td> der zu übertragende Datensatz </td></tr>
  2452. </table>
  2453. </ul>
  2454. <br>
  2455. <b>logFormat BSD:</b> <br><br>
  2456. "&lt;PRIVAL&gt;MONTH DAY TIME MYHOST IDENT[PID]: MESSAGE" <br><br>
  2457. <ul>
  2458. <table>
  2459. <colgroup> <col width=10%> <col width=90%> </colgroup>
  2460. <tr><td> PRIVAL </td><td> Priority Wert (kodiert aus "facility" und "severity") </td></tr>
  2461. <tr><td> MONTH </td><td> Monatsangabe nach RFC3164 </td></tr>
  2462. <tr><td> DAY </td><td> Tag des Monats nach RFC3164 </td></tr>
  2463. <tr><td> TIME </td><td> Zeitangabe nach RFC3164 </td></tr>
  2464. <tr><td> MYHOST </td><td> Internal MYHOST </td></tr>
  2465. <tr><td> TAG </td><td> Ident-Tag aus DEF wenn angegeben, sonst der eigene Devicename. Die Angabe wird mit "_fhem" (FHEM-Log) bzw. "_event" (Event-Log) ergänzt. </td></tr>
  2466. <tr><td> PID </td><td> Die ID der Mitteilung (= Sequenznummer) </td></tr>
  2467. <tr><td> MESSAGE </td><td> der zu übertragende Datensatz </td></tr>
  2468. </table>
  2469. </ul>
  2470. <br>
  2471. </ul>
  2472. <br><br>
  2473. <a name="Log2SyslogSet"></a>
  2474. <b>Set</b>
  2475. <ul>
  2476. <br>
  2477. <ul>
  2478. <li><b>reopen </b><br>
  2479. <br>
  2480. Schließt eine bestehende Client/Server-Verbindung und öffnet sie erneut.
  2481. Der Befehl kann z.B. bei "broken pipe"-Fehlern hilfreich sein.
  2482. </li>
  2483. </ul>
  2484. <br>
  2485. <ul>
  2486. <li><b>sendTestMessage [&lt;Message&gt;] </b><br>
  2487. <br>
  2488. Mit einem Devicetyp "Sender" kann abhängig vom Attribut "logFormat" eine Testnachricht im BSD- bzw. IETF-Format
  2489. gesendet werden. Wird eine optionale eigene &lt;Message&gt; angegeben, wird diese Nachricht im raw-Format ohne
  2490. Formatanpassung (BSD/IETF) gesendet. Das Attribut "disable = maintenance" legt fest, dass keine Daten ausser eine
  2491. Testnachricht an den Empfänger gesendet wird.
  2492. </li>
  2493. </ul>
  2494. <br>
  2495. </ul>
  2496. <br>
  2497. <a name="Log2SyslogGet"></a>
  2498. <b>Get</b>
  2499. <ul>
  2500. <br>
  2501. <ul>
  2502. <li><b>certinfo </b><br>
  2503. <br>
  2504. Zeigt auf einem Sender-Device Informationen zum Serverzertifikat an sofern eine TLS-Session aufgebaut wurde
  2505. (Reading "SSL_Version" ist nicht "n.a.").
  2506. </li>
  2507. </ul>
  2508. <br>
  2509. <ul>
  2510. <li><b>versionNotes </b><br>
  2511. <br>
  2512. Zeigt Release Informationen und Hinweise zum Modul an. Es sind nur Informationen mit Bedeutung für den Modulnutzer
  2513. enthalten.
  2514. </li>
  2515. </ul>
  2516. <br>
  2517. </ul>
  2518. <br>
  2519. <a name="Log2Syslogattr"></a>
  2520. <b>Attribute</b>
  2521. <ul>
  2522. <br>
  2523. <ul>
  2524. <a name="addTimestamp"></a>
  2525. <li><b>addTimestamp </b><br>
  2526. <br/>
  2527. Das Attribut ist nur für "Sender" verwendbar. Wenn gesetzt, werden FHEM Timestamps im Content-Feld der Syslog-Meldung
  2528. mit übertragen.<br>
  2529. Per default werden die Timestamps nicht im Content-Feld hinzugefügt, da innerhalb der Syslog-Meldungen im IETF- bzw.
  2530. BSD-Format bereits Zeitstempel gemäß RFC-Vorgabe erstellt werden.<br>
  2531. Die Einstellung kann hilfeich sein wenn mseclog in FHEM aktiviert ist.<br>
  2532. <br/>
  2533. Beispielausgabe (raw) eines Splunk Syslog Servers:<br/>
  2534. <pre>Aug 18 21:26:55 fhemtest.myds.me 1 2017-08-18T21:26:55 fhemtest.myds.me Test_event 13339 FHEM - : 2017-08-18 21:26:55 USV state: OL
  2535. Aug 18 21:26:54 fhemtest.myds.me 1 2017-08-18T21:26:54 fhemtest.myds.me Test_event 13339 FHEM - : 2017-08-18 21:26:54 Bezug state: done
  2536. Aug 18 21:26:54 fhemtest.myds.me 1 2017-08-18T21:26:54 fhemtest.myds.me Test_event 13339 FHEM - : 2017-08-18 21:26:54 recalc_Bezug state: Next: 21:31:59
  2537. </pre>
  2538. </li>
  2539. </ul>
  2540. <br>
  2541. <ul>
  2542. <a name="addStateEvent"></a>
  2543. <li><b>addStateEvent </b><br>
  2544. <br>
  2545. Das Attribut ist nur für "Sender" verwendbar. Wenn gesetzt, werden state-events mit dem Reading "state" ergänzt.<br>
  2546. Die Standardeinstellung ist ohne state-Ergänzung.
  2547. </li>
  2548. </ul>
  2549. <br>
  2550. <br>
  2551. <ul>
  2552. <a name="contDelimiter"></a>
  2553. <li><b>contDelimiter </b><br>
  2554. <br>
  2555. Das Attribut ist nur für "Sender" verwendbar. Es enthält ein zusätzliches Zeichen welches unmittelber vor das
  2556. Content-Feld eingefügt wird. <br>
  2557. Diese Möglichkeit ist in manchen speziellen Fällen hilfreich (z.B. kann das Zeichen ':' eingefügt werden um eine
  2558. ordnungsgemäße Anzeige im Synology-Protokollcenter zu erhalten).
  2559. </li>
  2560. </ul>
  2561. <br>
  2562. <br>
  2563. <ul>
  2564. <a name="disable"></a>
  2565. <li><b>disable [1 | 0 | maintenance] </b><br>
  2566. <br>
  2567. Das Device wird aktiviert, deaktiviert bzw. in den Maintenance-Mode geschaltet. Im Maintenance-Mode kann mit dem
  2568. "Sender"-Device eine Testnachricht gesendet werden (siehe "set &lt;name&gt; sendTestMessage").
  2569. </li>
  2570. </ul>
  2571. <br>
  2572. <br>
  2573. <ul>
  2574. <a name="logFormat"></a>
  2575. <li><b>logFormat [ BSD | IETF ]</b><br>
  2576. <br>
  2577. Das Attribut ist nur für "Sender" verwendbar. Es stellt das Protokollformat ein. (default: "IETF") <br>
  2578. </li>
  2579. </ul>
  2580. <br>
  2581. <br>
  2582. <ul>
  2583. <a name="makeEvent"></a>
  2584. <li><b>makeEvent [ intern | no | reading ]</b><br>
  2585. <br>
  2586. Das Attribut ist nur für "Collector" verwendbar. Mit dem Attribut wird das Verhalten der Event- bzw.
  2587. Readinggenerierung festgelegt.
  2588. <br><br>
  2589. <ul>
  2590. <table>
  2591. <colgroup> <col width=10%> <col width=90%> </colgroup>
  2592. <tr><td> <b>intern</b> </td><td> Events werden modulintern generiert und sind nur im Eventmonitor sichtbar. Readings werden nicht erstellt. </td></tr>
  2593. <tr><td> <b>no</b> </td><td> es werden nur Readings der Form "MSG_&lt;Hostname&gt;" ohne Eventfunktion erstellt </td></tr>
  2594. <tr><td> <b>reading</b> </td><td> es werden Readings der Form "MSG_&lt;Hostname&gt;" erstellt. Events werden in Abhängigkeit der "event-on-.*"-Attribute generiert </td></tr>
  2595. </table>
  2596. </ul>
  2597. </li>
  2598. </ul>
  2599. <br>
  2600. <br>
  2601. <ul>
  2602. <a name="octetCount"></a>
  2603. <li><b>octetCount </b><br>
  2604. <br>
  2605. Das Attribut ist nur für "Sender" verfügbar. <br>
  2606. Wenn gesetzt, wird das Syslog Framing von Non-Transparent-Framing (default) in Octet-Framing geändert.
  2607. Der Syslog-Empfänger muss Octet-Framing unterstützen !
  2608. Für weitere Informationen siehe RFC6587 <a href="https://tools.ietf.org/html/rfc6587">"Transmission of Syslog Messages
  2609. over TCP"</a>.
  2610. </li>
  2611. </ul>
  2612. <br>
  2613. <br>
  2614. <ul>
  2615. <a name="outputFields"></a>
  2616. <li><b>outputFields </b><br>
  2617. <br>
  2618. Das Attribut ist nur für "Collector" verwendbar.
  2619. Über eine sortierbare Liste können die gewünschten Felder des generierten Events ausgewählt werden.
  2620. Die abhängig vom Attribut <b>"parseProfil"</b> sinnvoll verwendbaren Felder und deren Bedeutung ist der Beschreibung
  2621. des Attributs "parseProfil" zu entnehmen.
  2622. Ist "outputFields" nicht gesetzt, wird ein vordefinierter Satz Felder zur Eventgenerierung verwendet.
  2623. </li>
  2624. </ul>
  2625. <br>
  2626. <br>
  2627. <ul>
  2628. <a name="parseFn"></a>
  2629. <li><b>parseFn {&lt;Parsefunktion&gt;} </b><br>
  2630. <br>
  2631. Das Attribut ist nur für Device-MODEL "Collector" verwendbar. Es wird die eingegebene Perl-Funktion auf die
  2632. empfangene Syslog-Meldung angewendet. Der Funktion werden folgende Variablen übergeben die zur Verarbeitung
  2633. und zur Werterückgabe genutzt werden können. Leer übergebene Variablen sind als "" gekennzeichnet. <br>
  2634. Das erwartete Rückgabeformat einer Variable wird in "()" angegeben sofern sie Restriktionen unterliegt.
  2635. Ansonsten ist die Variable frei verfügbar.
  2636. <br><br>
  2637. <ul>
  2638. <table>
  2639. <colgroup> <col width=20%> <col width=80%> </colgroup>
  2640. <tr><td> $PRIVAL </td><td> "" (0 ... 191) </td></tr>
  2641. <tr><td> $FAC </td><td> "" (0 ... 23) </td></tr>
  2642. <tr><td> $SEV </td><td> "" (0 ... 7) </td></tr>
  2643. <tr><td> $TS </td><td> Zeitstempel (YYYY-MM-DD hh:mm:ss) </td></tr>
  2644. <tr><td> $HOST </td><td> "" </td></tr>
  2645. <tr><td> $DATE </td><td> "" (YYYY-MM-DD) </td></tr>
  2646. <tr><td> $TIME </td><td> "" (hh:mm:ss) </td></tr>
  2647. <tr><td> $ID </td><td> "" </td></tr>
  2648. <tr><td> $PID </td><td> "" </td></tr>
  2649. <tr><td> $MID </td><td> "" </td></tr>
  2650. <tr><td> $SDFIELD </td><td> "" </td></tr>
  2651. <tr><td> $CONT </td><td> "" </td></tr>
  2652. <tr><td> $DATA </td><td> übergebene Rohdaten der Syslog-Mitteilung (keine Rückgabeauswertung!) </td></tr>
  2653. <tr><td> $IGNORE </td><td> 0 (0|1), wenn $IGNORE==1 wird der Syslog-Datensatz ignoriert </td></tr>
  2654. </table>
  2655. </ul>
  2656. <br>
  2657. Die Variablennamen korrespondieren mit den Feldnamen und deren ursprünglicher Bedeutung angegeben im Attribut
  2658. <b>"parseProfile"</b> (Erläuterung der Felddaten). <br><br>
  2659. <ul>
  2660. <b>Beispiel: </b> <br>
  2661. # Quelltext: '<4> <;4>LAN IP and mask changed to 192.168.2.3 255.255.255.0' <br>
  2662. # Die Zeichen '<;4>' sollen aus dem CONT-Feld entfernt werden
  2663. <pre>
  2664. {
  2665. ($PRIVAL,$CONT) = ($DATA =~ /^<(\d{1,3})>\s(.*)$/);
  2666. $CONT = (split(">",$CONT))[1] if($CONT =~ /^<.*>.*$/);
  2667. }
  2668. </pre>
  2669. </ul>
  2670. </li>
  2671. </ul>
  2672. <br>
  2673. <br>
  2674. <ul>
  2675. <a name="parseProfile"></a>
  2676. <li><b>parseProfile [ BSD | IETF | ... | ParseFn | raw ] </b><br>
  2677. <br>
  2678. Auswahl eines Parsing-Profiles. Das Attribut ist nur für Device-Model "Collector" verwendbar.
  2679. <br><br>
  2680. <ul>
  2681. <table>
  2682. <colgroup> <col width=20%> <col width=80%> </colgroup>
  2683. <tr><td> <b>BSD</b> </td><td> Parsing der Meldungen im BSD-Format nach RFC3164 </td></tr>
  2684. <tr><td> <b>IETF</b> </td><td> Parsing der Meldungen im IETF-Format nach RFC5424 (default) </td></tr>
  2685. <tr><td> <b>...</b> </td><td> Es werden weitere angepasste Parsingprofile für ausgewählte Geräte angeboten </td></tr>
  2686. <tr><td> <b>ParseFn</b> </td><td> Verwendung einer eigenen spezifischen Parsingfunktion im Attribut "parseFn". </td></tr>
  2687. <tr><td> <b>raw</b> </td><td> kein Parsing, die Meldungen werden wie empfangen in ein Event umgesetzt </td></tr>
  2688. </table>
  2689. </ul>
  2690. <br>
  2691. Die geparsten Informationen werden in Feldern zur Verfügung gestellt. Die im Event erscheinenden Felder und deren
  2692. Reihenfolge können mit dem Attribut <b>"outputFields"</b> bestimmt werden. <br>
  2693. Abhängig vom verwendeten "parseProfile" werden die folgenden Felder mit Werten gefüllt und es ist dementsprechend auch
  2694. nur sinnvoll die benannten Felder in Attribut "outputFields" zu verwenden. Im raw-Profil werden die empfangenen Daten
  2695. ohne Parsing in ein Event umgewandelt.
  2696. <br><br>
  2697. Die sinnvoll im Attribut "outputFields" verwendbaren Felder des jeweilgen Profils sind:
  2698. <br>
  2699. <br>
  2700. <ul>
  2701. <table>
  2702. <colgroup> <col width=10%> <col width=90%> </colgroup>
  2703. <tr><td> BSD </td><td>-> PRIVAL,FAC,SEV,TS,HOST,ID,CONT </td></tr>
  2704. <tr><td> IETF </td><td>-> PRIVAL,FAC,SEV,TS,HOST,DATE,TIME,ID,PID,MID,SDFIELD,CONT </td></tr>
  2705. <tr><td> ParseFn </td><td>-> PRIVAL,FAC,SEV,TS,HOST,DATE,TIME,ID,PID,MID,SDFIELD,CONT </td></tr>
  2706. <tr><td> raw </td><td>-> keine Auswahl sinnvoll, es wird immer die Originalmeldung in einen Event umgesetzt </td></tr>
  2707. </table>
  2708. </ul>
  2709. <br>
  2710. Erläuterung der Felddaten:
  2711. <br>
  2712. <br>
  2713. <ul>
  2714. <table>
  2715. <colgroup> <col width=20%> <col width=80%> </colgroup>
  2716. <tr><td> PRIVAL </td><td> kodierter Priority Wert (kodiert aus "facility" und "severity") </td></tr>
  2717. <tr><td> FAC </td><td> Kategorie (Facility) </td></tr>
  2718. <tr><td> SEV </td><td> Schweregrad der Meldung (Severity) </td></tr>
  2719. <tr><td> TS </td><td> Zeitstempel aus Datum und Zeit (YYYY-MM-DD hh:mm:ss) </td></tr>
  2720. <tr><td> HOST </td><td> Hostname / Ip-Adresse des Senders </td></tr>
  2721. <tr><td> DATE </td><td> Datum (YYYY-MM-DD) </td></tr>
  2722. <tr><td> TIME </td><td> Zeit (hh:mm:ss) </td></tr>
  2723. <tr><td> ID </td><td> Gerät oder Applikation welche die Meldung gesendet hat </td></tr>
  2724. <tr><td> PID </td><td> Programm-ID, oft belegt durch Prozessname bzw. Prozess-ID </td></tr>
  2725. <tr><td> MID </td><td> Typ der Mitteilung (beliebiger String) </td></tr>
  2726. <tr><td> SDFIELD </td><td> Metadaten über die empfangene Syslog-Mitteilung </td></tr>
  2727. <tr><td> CONT </td><td> Inhalt der Meldung </td></tr>
  2728. <tr><td> DATA </td><td> empfangene Rohdaten </td></tr>
  2729. </table>
  2730. </ul>
  2731. <br>
  2732. </li>
  2733. </ul>
  2734. <br>
  2735. <br>
  2736. <ul>
  2737. <a name="port"></a>
  2738. <li><b>port &lt;Port&gt;</b><br>
  2739. <br>
  2740. Der verwendete Port. Für einen Sender ist der default-Port 514, für einen Collector (Syslog-Server) der Port 1514.
  2741. </li>
  2742. </ul>
  2743. <br>
  2744. <br>
  2745. <ul>
  2746. <a name="protocol"></a>
  2747. <li><b>protocol [ TCP | UDP ]</b><br>
  2748. <br>
  2749. Setzt den Protokolltyp der verwendet werden soll. Es kann UDP oder TCP gewählt werden. <br>
  2750. Standard ist "UDP" wenn nichts spezifiziert ist.
  2751. </li>
  2752. </ul>
  2753. <br>
  2754. <br>
  2755. <ul>
  2756. <a name="rateCalcRerun"></a>
  2757. <li><b>rateCalcRerun &lt;Zeit in Sekunden&gt; </b><br>
  2758. <br>
  2759. Wiederholungszyklus für die Bestimmung der Log-Transferrate (Reading "Transfered_logs_per_minute") in Sekunden (>=60).
  2760. Eingegebene Werte <60 Sekunden werden automatisch auf 60 Sekunden korrigiert.
  2761. Default sind 60 Sekunden.
  2762. </li>
  2763. </ul>
  2764. <br>
  2765. <br>
  2766. <ul>
  2767. <a name="respectSeverity"></a>
  2768. <li><b>respectSeverity </b><br>
  2769. <br>
  2770. Es werden nur Nachrichten übermittelt (Sender) bzw. beim Empfang berücksichtigt (Collector), deren Schweregrad im
  2771. Attribut enthalten ist.
  2772. Ist "respectSeverity" nicht gesetzt, werden Nachrichten aller Schweregrade verarbeitet.
  2773. </li>
  2774. </ul>
  2775. <br>
  2776. <br>
  2777. <ul>
  2778. <a name="sslCertPrefix"></a>
  2779. <li><b>sslCertPrefix</b><br>
  2780. <br>
  2781. Setzt das Präfix der SSL-Zertifikate, die Voreinstellung ist "certs/server-".
  2782. Mit diesem Attribut kann für verschiedene Log2Syslog-Devices die Verwendung unterschiedlicher SSL-Zertifikate
  2783. bestimmt werden.
  2784. Siehe auch das "TLS" Attribut.
  2785. </li>
  2786. </ul>
  2787. <br>
  2788. <br>
  2789. <ul>
  2790. <a name="ssldebug"></a>
  2791. <li><b>ssldebug</b><br>
  2792. <br>
  2793. Debugging Level von SSL Messages. Das Attribut ist nur für Device-MODEL "Sender" verwendbar. <br><br>
  2794. <ul>
  2795. <li> 0 - Kein Debugging (default). </li>
  2796. <li> 1 - Ausgabe Errors von from <a href="http://search.cpan.org/~sullr/IO-Socket-SSL-2.056/lib/IO/Socket/SSL.pod">IO::Socket::SSL</a> und ciphers von <a href="http://search.cpan.org/~mikem/Net-SSLeay-1.85/lib/Net/SSLeay.pod">Net::SSLeay</a>. </li>
  2797. <li> 2 - zusätzliche Ausgabe von Informationen über den Protokollfluss von <a href="http://search.cpan.org/~sullr/IO-Socket-SSL-2.056/lib/IO/Socket/SSL.pod">IO::Socket::SSL</a> und Fortschrittinformationen von <a href="http://search.cpan.org/~mikem/Net-SSLeay-1.85/lib/Net/SSLeay.pod">Net::SSLeay</a>. </li>
  2798. <li> 3 - zusätzliche Ausgabe einiger Dumps von <a href="http://search.cpan.org/~sullr/IO-Socket-SSL-2.056/lib/IO/Socket/SSL.pod">IO::Socket::SSL</a> und <a href="http://search.cpan.org/~mikem/Net-SSLeay-1.85/lib/Net/SSLeay.pod">Net::SSLeay</a>. </li>
  2799. </ul>
  2800. </li>
  2801. </ul>
  2802. <br>
  2803. <br>
  2804. <ul>
  2805. <a name="TLS"></a>
  2806. <li><b>TLS</b><br>
  2807. <br>
  2808. Ein Client (Sender) baut eine gesicherte Verbindung zum Syslog-Server auf.
  2809. Ein Syslog-Server (Collector) stellt eine gesicherte Verbindung zur Verfügung.
  2810. Das Protokoll schaltet automatisch auf TCP um.
  2811. <br<br>
  2812. Damit ein Collector TLS verwenden kann, muss ein Zertifikat erstellt werden bzw. vorhanden sein.
  2813. Mit folgenden Schritten kann ein Zertifikat erzeugt werden: <br><br>
  2814. 1. im FHEM-Basisordner das Verzeichnis "certs" anlegen: <br>
  2815. <pre>
  2816. sudo mkdir /opt/fhem/certs
  2817. </pre>
  2818. 2. SSL Zertifikat erstellen: <br>
  2819. <pre>
  2820. cd /opt/fhem/certs
  2821. sudo openssl req -new -x509 -nodes -out server-cert.pem -days 3650 -keyout server-key.pem
  2822. </pre>
  2823. 3. Datei/Verzeichnis-Rechte setzen: <br>
  2824. <pre>
  2825. sudo chown -R fhem:dialout /opt/fhem/certs
  2826. sudo chmod 644 /opt/fhem/certs/*.pem
  2827. sudo chmod 711 /opt/fhem/certs
  2828. </pre>
  2829. </li>
  2830. </ul>
  2831. <br>
  2832. <br>
  2833. <ul>
  2834. <a name="timeout"></a>
  2835. <li><b>timeout</b><br>
  2836. <br>
  2837. Das Attribut ist nur für "Sender" verwendbar.
  2838. Timeout für die Verbindung zum Syslog-Server (TCP). Default: 0.5s.
  2839. </li>
  2840. </ul>
  2841. <br>
  2842. <br>
  2843. <ul>
  2844. <a name="verbose"></a>
  2845. <li><b>verbose</b><br>
  2846. <br>
  2847. Verbose-Level entsprechend dem globalen <a href="#attributes">Attribut</a> "verbose".
  2848. Die Ausgaben der Verbose-Level von Log2Syslog-Devices werden ausschließlich im lokalen FHEM Logfile ausgegeben und
  2849. nicht weitergeleitet um Schleifen zu vermeiden.
  2850. </li>
  2851. </ul>
  2852. <br>
  2853. <br>
  2854. </ul>
  2855. <br>
  2856. <a name="Log2Syslogreadings"></a>
  2857. <b>Readings</b>
  2858. <ul>
  2859. <br>
  2860. <table>
  2861. <colgroup> <col width=35%> <col width=65%> </colgroup>
  2862. <tr><td><b>MSG_&lt;Host&gt;</b> </td><td> die letzte erfolgreich geparste Syslog-Message von &lt;Host&gt; </td></tr>
  2863. <tr><td><b>Parse_Err_No</b> </td><td> die Anzahl der Parse-Fehler seit Start </td></tr>
  2864. <tr><td><b>SSL_Algorithm</b> </td><td> der verwendete SSL Algorithmus wenn SSL eingeschaltet und aktiv ist </td></tr>
  2865. <tr><td><b>SSL_Version</b> </td><td> die verwendete TLS-Version wenn die Verschlüsselung aktiv ist</td></tr>
  2866. <tr><td><b>Transfered_logs_per_minute</b> </td><td> die durchschnittliche Anzahl der übertragenen/empfangenen Logs/Events pro Minute </td></tr>
  2867. </table>
  2868. <br>
  2869. </ul>
  2870. </ul>
  2871. =end html_DE
  2872. =cut