SDN - Lync Dialog Listener (LDL)
Der Lync Dialog Listener ist ein Serverprozess, der auf jedem Lync Frontend Server zu installieren ist und als CsTrustedApplication die SIP-Dialoge mit überwacht und Metadaten extrahiert und an den Lync Dialog Manager weiter gibt. Diese Seite beschreibt Installation aber auch Hintergründe und Funktionsweise.
There is an short english version available at SDN Live View
Hinweis:
Normalerweise installiert man zuerst das
Backend, d.h. den LDM ehe man den LDL
einrichtet.
Download
Die Installationskomponente ist Bestandteil des Lync SDN API, welches kostenfrei herunter geladen werden kann.
Lync SDN Interface
Version 2.1
http://www.microsoft.com/en-us/download/details.aspx?id=44274
Aus dem Paket benötigen sie das Paket "LyncSDNAPI.msi".
Installation Lync Dialog Listener
Der Lync Dialog Listener verbirgt sich in dem API-Paket, welches nur auf einem Lync Frontend installiert werden kann. Darauf weist Sie das Setup auch am Anfang gleich hin:
Sollten sie bereits die Version 2.0 installiert haben, dann müssen Sie diese zuerst manuell deinstallieren. Die Version 2.1 ersetzt nicht alleine die Vorgängerversion sondern verhindert die Installation.
Hinweis
Per Default installiert sich der LDL nach
"C:\Program Files\Microsoft Lync
Server\Microsoft Lync Dialog Listener\". Er funktioniert
auch mit Lync 2010. Auf einem Lync 2013
Server sollten Sie den Pfad vielleicht anpassen,
damit im Programmverzeichnis kein weiteres
Verzeichnis "neben Lync 2013" auftaucht.
Bei der Wahl des Zielverzeichnisses sollten Sie überlegen, ob sie das LOG-Verzeichnis vielleicht nicht gerade in das TEMP-Verzeichniss des aktuell installierenden Benutzers legen lassen. Ich habe das auf "C:\Program Files\Microsoft Lync Server\Microsoft Lync Dialog Listener\SDNLOG" geändert.
Im zweiten Schritt müssen Sie hinterlegen, wohin der LDL die Daten sendet.
Die drei Optionen führen zu drei unterschiedlichen Folgedialogen.
- Colocated
Die Daten werden lokal an einen LDM gesendet. - Pool mit PoolFQDN
Hierbei unterstützt der LDL optional die Abfrage eines SRV-Record
Der Dienst sucht dabei nach einen _sdninternal._https.<domain>, der als SRV-Record den Namen und Port des Zielsystems mit dem LDM enthält
Siehe auch "Setting up DNS SRV record " http://msdn.microsoft.com/en-us/library/office/dn785198(v=office.15).aspx
Ohne SRV-Record kann ein FQDN angegeben werden:
- Active/Standby
Hierbei müssen Sie dann die beiden FQDN-Adressen eingeben
Ich nutze in der Regel den "Pool", weil ich damit einen Namen hinterlege und wer heute schon mit Hochverfügbarkeit" arbeitet, wird sowieso mit Loadbalancern arbeiten.
Seit der Version 2.1 kann nun auch eine Authentifizierung zwischen dem LDL und dem LDM vorgegeben werden.
Dienstkonto
Laut Release Notes installiert der Lync Dialog Watcher einen
Windows Dienste, welcher sich mit einem
Domänen-Benutzer anmelden kann. Dieses Konto
muss aber in der lokalen Gruppe "RTC Server Applications"
Mitglied sein.
Bei der Installation werden Sie nach der Anmeldung gefragt. "Network Service Account" ist per Default ausgewählt.
Wenn Sie stattdessen ein Dienstkonto verwenden wollen, dann müssen Sie im nächsten Dialog die Anmeldedaten eingeben.
Hinweis: Manchmal stellt das Setup dies nicht korrekt ein. Prüfen Sie dies nach der Installation, Update oder Reparatur, ob der Dienst immer noch mit dem Konto konfiguriert ist
Mehr passiert erst einmal nicht. Der Dienst startet, überwacht die SIP Dialoge und meldet diese per HTTP an den hinterlegten SDN Manager. Der Dienst wird als "Automatic (Delayed)" gestartet und ist von den Diensten "CNG Key Isolation" und natürlich "Lync Server Front-End" abhängig.
Blick hinter das Setup
Ich habe die API erst auf meinem Notebook im ICE untersucht und da hatte ich kleinen Lync Server zur Hand. Aber ein MSI-Paket lässt sich ja auch auch so auspacken.
REM Entpacken des MSI Archiv
msiexec /a D:\SDN\LyncSDNAPI.msi /qb
TARGETDIR=D:\SDN\sdk
Danach hatte ich eine entsprechende Verzeichnisstruktur mit vielen einzelnen Dateien. Das gibt eine Vorschau auf die Installation auf dem Server.
Sie erkennen hier das eigentliche Dienstprogramm und einige DLLs drum herum. Interessant fand ich z.B.: die ServerAgent.dll, die den "dritten" Weg bei der MSPL-Schnittstelle aufzeigt.
Unter dem Verzeichnis ProgramData\Microsoft\Lync SDN API finden Sie eine REGISTER.PS1, die erst ein paar alte Eventlog-Quellen entfernt, die QoE Einrichtung prüft und ggfls. sie wart, dass ohne QoE keine QoE-Daten gemeldet werden können. Zuletzt registriert das Skript die CsTrustedApplication mit folgenden Parametern.
New-CsServerApplication `
-Identity $registerMe -Uri
http://www.microsoft.com/LC/NetworkEnlightenment
`
-Enabled $true `
-Critical $false `
-Priority 0
Dann wartet die CMS-Replikation ab und starten den vorher schon durch das MSI installierten Dienst "Lync Dialog Listener". Wenn Sie die Konfiguration beim Setup korrekt eingegeben haben, ist die Einrichtung auf dem Frontend schon abgeschlossen.
Konfig-Datei
Schaut man in das Programmverzeichnis des soeben installierten Diensts, dann finden Sie eine .NET-typische Konfigurationsdatei, die den gleichen Namen wie die EXE hat und die Extension ".CONFIG" hat.
Diese Datei ist sehr interessant, da sie zum einen die beim Setup gemachten Einstellungen beinhaltet aber noch viel mehr auch Einstellungen eröffnet, die meine Aufmerksamkeit auf sich gezogen haben. Einfach zu finden ist noch die URL des Servers. (Auszug)
<?xml version="1.0" encoding="utf-8" ?> <configuration> <appSettings> <add key="submituri" value="http://nawex13:80/LDL"/> <!-- URI to locate the LSM (used unless checkdns is true) --> <add key="submituri2" value="http://localhost:9333/LDL"/> <!-- URI to locate the LSM (used unless checkdns is true) --> <add key="alternativeuri" value=""/> <!-- secondary URI to locate an LSM, in case the primäry is unavailable in a Active/Standby configuration --> <add key="clientcertificateid" value=""/> <!-- thumbprint of a client certificate to use to authenticate the LDL with the LSM --> <add key="checkdns" value="False"/> <!-- use a URI provided by the DNS SRV record für locating a pool of LSMs --> </appSettings> </configuration>
LDL Protokollierung
Interessant sind aber auch die Logging-Funktionen. Die Ausgabedateien und deren Formatierung werden in der XML-Datei definiert.
Achtung:
Die Protokolldateien werden nicht automatisch
nach Ablauf einer Zeit gelöscht. Sie sollten
ihre Server überwachen, um Engpässe bei der
Festplattenkapazität zu erkennen und vielleicht
die alten Dateien auch löschen, z.B.: durch
einen geplanten Task
.NET-typisch werden zuerst Listener und Formatter definiert. Das sind alles "FileWriter", die nach 10 Megabyte eine neue Datei anfangen und jeden Tag eine neue Datei anlegen. Zudem werden über "Formatter" die Ausgaben umgestaltet:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <loggingConfiguration name="" tracingEnabled="true" defaultCategory="Error"> <listeners> <add name="LNEAppLog" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.RollingFlatFileTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.RollingFlatFileTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" fileName="%TEMP%\LNEApp.log" footer="" formatter="LNEDetailFormatter" header="" rollFileExistsBehavior="Increment" rollInterval="Day" rollSizeKB="10000" traceOutputOptions="LogicalOperationStack, DateTime, Timestamp, ProcessId, ThreadId, Callstack" /> <add name="AllDataLog" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.RollingFlatFileTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.RollingFlatFileTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" fileName="%TEMP%\AllData.log" footer="" formatter="SimpleOutput" header="" rollFileExistsBehavior="Increment" rollInterval="Day" rollSizeKB="10000" /> <add name="QoEInputDataLog" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.RollingFlatFileTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.RollingFlatFileTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" fileName="%TEMP%\QoEInputData.log" footer="" formatter="SimpleOutput" header="" rollFileExistsBehavior="Increment" rollInterval="Day" rollSizeKB="10000" /> <formatters> <add type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" template="{timestamp(local:O)}{tab}{message}{tab}{dictionary({tab}{key}: {value})}" name="LNEOverviewFormatter" /> <add type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" template="{timestamp(local:O)}{tab}[{category}]{tab}{message}{tab}{dictionary({tab}{key}: {value})}" name="LNEDetailFormatter" /> <add type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" template="{message}{newline}" name="SimpleOutput" /> </formatters>
Schon der Lync Dialog Listener kann also mehr als nur die SIP-Dialoge an den Lync Dialog Manager senden, sondern schon selbst loggen. Allerdings muss die Funktion aktiviert sein. Dazu gibt es weitere "Schalter":
<?xml version="1.0" encoding="utf-8" ?> <configuration> <loggingConfiguration name="" tracingEnabled="true" defaultCategory="Error"> <categorySources> <add switchValue="Off" name="Debug"> <listeners> <add name="LNEAppLog" /> </listeners> </add> <add switchValue="All" name="Init"> <listeners> <add name="LNEAppLog" /> </listeners> </add> <add switchValue="All" name="Error"> <listeners> <add name="LNEAppLog" /> </listeners> </add> <add switchValue="All" name="Settings"> <listeners> <add name="LNEAppLog" /> </listeners> </add> <add switchValue="All" name="CleanUp"> <listeners> <add name="LNEAppLog" /> </listeners> </add> <add switchValue="Off" name="QoEInputData"> <listeners> <add name="QoEInputDataLog" /> <add name="AllDataLog" /> </listeners> </add> <add switchValue="Off" name="DialogData"> <listeners> <add name="AllDataLog" /> <add name="DialogDataLog" /> </listeners> </add>
Dies ist nur eine Teilmenge aber es ist unschwer zu erkennen, das "Init", "Error", Settings" auf "ALL" steht, während "DEBUG" aber auch "QoEInputData" und "DialogData" auf "Off" steht.
LDL QoE Protokollierung
Das ist aber noch noch alles, denn passend zur QoE gibt es noch Einstellungen, mit denen anscheinend eine Datenbank mit Anmeldedaten hinterlegt werden kann:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <appSettings> ... <add key="qoedatabasename" value="" /> <add key="qoedatabaseUsername" value="" /> <add key="qoedatabasepassword" value="" />
Leider weiß ich nicht, wie die Daten hier anzugeben sind, ob der LDL auf die Lync QoE-Datenbank zugreifen will oder dies eine autarke Datenbank ist. Weiter unten im XML-File werden dann sogar noch Grenzwerte definiert. Hier ein Auszug:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <appSettings> <add key="audio-DegradationAvgOptimal" value="0.6" /> <add key="audio-DegradationAvgAcceptable" value="1" /> <add key="audio-RoundTripOptimal" value="200" /> <add key="audio-RoundTripAcceptable" value="500" /> <add key="audio-PacketLossRateOptimal" value="0.02" /> <add key="audio-PacketLossRateAcceptable" value="0.05" /> <add key="audio-JitterInterArrivalOptimal" value="15" /> <add key="audio-JitterInterArrivalAcceptable" value="25" /> <add key="audio-RatioConcealedSamplesAvgOptimal" value="0.03" />
Vielleicht können Sie nun verstehen, warum mich die "Lync SDN API" elektrisiert hat. Ich hatte schon länger vor ein MSPL-Skript zu schreiben, welches auf dem Server aus den SIP-Dialogen z.B. solche Daten extrahiert und auch erfasst, welche "INVITE" und "BYE"-Pakete einen Verbindungsaufbau und Abbau anzeigen. Mit der Lync SDN API scheint Microsoft schon ein fertiges Modul mir zu liefern.
Und ich werde den Verdacht nicht los, dass dieses Modul in Office 365 vielleicht schon aktiv für die Überwachung von Lync Servern genutzt wird, denn so lassen sich auch Fehler quasi in Realtime erkennen. Doch dazu später mehr.
Dienst manuell aufrufen
Auch wenn das Setup den Dienst schon komplett installiert hat, können Sie die EXE auch interaktiv in einer CMD-Box starten.
Achtung:
Per Default läuft der Dienst als "Network
Service" und hat ausreichend Rechte. Wird er als
"Benutzer" gestartet, muss das Konto Mitglied
der lokalen Gruppe "RTC Server Applications"
sein.
Natürlich beschwert sich das Programm, dass es kein Dienst ist und ohne Berechtigungen kann er auch keine Performance Counter anlegen und auf meiner Workstation kommt das Programm schon gar nicht an einen Lync Server. Aber sie können so natürlich Fehler beim Start erkennen.
Zudem ist schön zu sehen, dass das Programm eine Verbindung zum Server aufbaut und nicht umgekehrt. Dazu versucht es den "Lync ServerAgent" zu erreichen.
SIP Adress Obfuscator
Wenn Sie sich die XML-Daten anschauen, dann erkennen sie hier nicht, dass der UserPart der SIP-Adresse eigentlich "frank.carius" lautet. Der Default scheint der LDL den Userpart einer SIP-Adresse zu "verstümmeln". Ich tippe auf einen einfachen Hash-Wert. Der Schutz ist aber nicht besonders hoch, denn auch wenn der Vorgang nicht reversibel ist, so ergibt der gleiche Eingabewert auch immer die gleiche Ausgabe. Ich brauche zumindest für die internen SIP-URIs einfach nur per CSV diese zu exportieren und dem Programm "SipObfuscator.exe" vorzuwerfen.
C:\SDN\sdk\Program Files\Microsoft Lync Server\Microsoft Lync SDN API\SipObfuscator.exe" frank.carius@msxfaq.net FB051BCCFF88FAD68E3BE528C9D8FE08@msxfaq.net
So kann ich mir ganz schnell eine eigene "Rainbow-Table" erstellen um jeder kryptischen SIP-URI den Klarnamen zuzuordnen.
Sie können diese unkenntlichmachung abschalten. In der Konfigurationsdatei stellen Sie den Wert von "hidepii" auf False.
Beim SDN SDK 2.1 ist der Key gar nicht mehr vorhanden, aber kann natürlich addiert werden
<add key="hidepii" value="False" /> <!-- Disable Obfuscation -->
Dann werden die SIP-URLs unverfälscht weiter gegeben. Das funktioniert auch mit SDN 2.1.
Eventlog
Der Lync Dialog Manager legt auch eine eigene Eventlog Kategorie an, die als eigener Eintrag zu sehen ist:
Folgende Eventlogs habe ich bislang gesehen.
Severity | Eventid | Text |
---|---|---|
Error |
0 |
Lync Dialog Listener failed: Could not contact the Lync ServerAgent and the Lync Front-End |
Information |
2 |
Identified a conversation with less than acceptable quality |
Error |
2 |
ERROR: Server unavailable |
Error |
3 |
ERROR: Must be running under an account that is a member of the "RTC Server Applications" local group |
Error |
8 |
Could not contact the Lync ServerAgent and the Lync Front-End |
Information |
101 |
Lync DialogListener NT Service started. |
Information |
104 |
The Service was stopped. |
Etwas irritiert mich die doppelvergabe der ID 2 für zwei unterschiedliche Events.
Performance Counter
DDer Lync Dialog Watcher installiert nicht nur ein Eventlog, sondern auch noch ein paar Performance Counter
Die Beschreibung der Felder liefert aber nur bedingt weitere Informationen
Counter | Beschreibung |
---|---|
# call messages failed |
Total number of send failures (regardless whether resending succeeded) |
# call messages sent overall |
Total number of call related messages sent successfully - counting every destination |
# messages / Sec |
Number of messages sent per second |
# messages attempted to send overall |
Number of messages overall attempted to send. |
# messages attempting to send |
Number of messages currently attempting to send. |
# messages failed processing |
Total number messages that failed during processing |
# Messages Received |
Total number of call related messages received |
# undeliverable messages |
Total number messages that were not received at a destination - even with attempting to resend |
# unique call messages sent |
Total number of unique call related messages attempted to sent (regardless of to how many destinations) |
length of longest queue |
Longest send message queue |
HTTP-Ziele, Sicherheit
Per Default erfolgt die Verbindung vom LDL-Service zum nächsten Hop per HTTP und damit unverschlüsselt. Auch konnte ich nicht sehen, dass der LDL irgendwie eine Authentifizierung unterstützt. Das ist aus Sicherheitsaspekten natürlich kritisch zu sehen aber auf der anderen Seite natürlich auch die einfachste Version. Da Server und Gegenstelle in der Regel in einem gesicherten Servernetz stehen, kann dies toleriert werden. Die SIP-URLs sind ja per Default zumindest "leicht" unkenntlich gemacht.
Das Backend, welches durch den Lync Dialog Manager bereit gestellt wird, bietet aber neben http/9333 auch noch eine https-Verbindung auf Port 9332 an. Seit SDN 2.1 kann der LDL sich gegenüber dem LDM auch mit einem Client Zertifikat ausweisen.
Weitere Links
- SDN Grundlagen
- SDN mit Lync
- SDN - Lync Dialog Manager
- SDN - Lync LDL2LDM
- Lync and Software-Defined
Networking
http://blogs.technet.com/b/lync/archive/2013/12/17/lync-and-software-defined-networking.aspx - Software-defined networking
http://de.wikipedia.org/wiki/Software-defined_networking - SDN, NFV & OpenFlow APIs and
SDKs
http://www.sdncentral.com/comprehensive-list-of-sdn-apis/ - SDN and Communications: A
Great Match
http://www.nojitter.com/post/240166256/sdn-and-communications-a-great-match/