93_Log2Syslog.pm 132 KB

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