RTP/RTCP – Realtime Transport/Control Protocol

Ponieważ ostatnio musiałem odświeżyc swoją wiedzę na temat RTP ponizej powtórka z przeszlosci. Poniższy post oparty jest bezpośrednio na dokumencie IETF RFC 3550 specyfikujacym bazowy protokol RTP.

RTP/RTCP są to protokóły przeznaczone do transmisji end2end sygnałów cyfrowych o charakterystyce ‘realtime’, takich jak dzwięk czy video. Został zaprojektowany w celu oddzielenia mechanizmów transmiscji danych i kontroli sesji. Z każdym strumieniem danych skojarzony jest oddzielny kanał RTP/RTCP zawierajaca po jednym porcie RTP i RTCP. RTP jest protokołem odpowiedzialnym za transmisje strumieni danych tak zwanych ‘RTP payload’. RTP samo w sobie nie zapewnia mechanizmów kontorli opoźnień czy stratności ale bazuje na wykorzystywanym protokole transportowym ktorym najcześciej jest to UDP. RTCP skolei jest odpowiedzialne za kontrole jakości swiadczonych uslug poprzez RTP (informowanie o ilosci gubionych pakietow, opoznieniach czy parametrach wykorzystywanych kodekow adaptacyjnych). Opcjonalnie dostarcza możliwość kontroli uczestnikow sesji, ale to najcześciej jest realizowane przez skojarzony z RTP protokół sygnalizacyjny tak jak np SIP.

RTP

Struktura pakietu

0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|V=2|P|X|  CC   |M|     PT      |       sequence number         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                           timestamp                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           synchronization source (SSRC) identifier            |
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|            contributing source (CSRC) identifiers             |
|                             ....                              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Pierwsze 12 oktetow wystepuje zawsze, opcjonalne pola CSRC wystepuja gdy na drodze danych jest mixer.

  • version (V): 2 bity – wersja obecnie 2
  • padding (P): 1 bit – wskazuje czy koniec pakietu jest uzupelniony zerami, jesli tak ostatni oktet wskazuje na liczbe oktetow do pominiecia
  • extension (X): 1 bit – wskazuje ze do pakietu dolaczony jest naglowek z rozszerzeniem
  • CSRC count (CC): 4 bity – wskazuje na liczbe identyfikatorw CSRC na koncu naglowka
  • marker (M): 1 bit – umozliwia wskazanie ze jest znaczacy pakiet, wykorzystywane przez profile RTP
  • payload type (PT): 7 bitów – określa format danych
  • sequence number: 16 bitów – numer sekwencyjny pakietu RTP, zwiekszany o jeden za każdym razem
  • timestamp: 32 bity – wartosc bezwgledna informujace o przedziale pomiedzy przesylanymi probkami danych
  • SSRC: 32 bity – identyfikuje zrodlo synchronizacji
  • CSRC list: od 0 tdo 15 , 32 bity każde – listaidentyfikatorow CSRC ktorych dane sa mixowane

RTCP

Zasada dzialanie RTCP polega na cyklicznej wymianie wiadomosci kontrolnych w oparciu o te same mechanizmy dystrubucji co RTP np. uzywajac innego portu udp. RTCP realizuje 4 podstawowe funkcje:
  • informowanie o jakosci dystrybucji danych oraz mozliwosciach adaptacji na poziomie kodowania
  • przenosi parametr CNAME odpowiedzialny za persystentna identyfikacje sesji RTP
  • ustala czestotliowsc wymiany pakietow w zaleznosci od liczby uczestnikow
  • opcjonalnie pozawala przenosic minimalna ilosc informacji identyfikujaca strony

Struktura pakietu

RFC 3550 definiuje pieć rodzajów pakietów, które przenoszą różne informacje kontrolne

  • SR (Sender Report) – statystyki transmisji i odbioru danych od aktywnych uczestnikow
  • RR (Receiver Report ) – statystyki odbioru dla nieaktywnych uczestnikow
  • SDES (Source Description) – parametry informacyjne zródła np CNAME
  • BYE – informuje o razlaczeniu
  • APP – informacje specyficzne dla danej aplikacji
Kazdy pakiet RTCP składa sie ze stałej części oraz następującej po niej czesci o zmiennej długosci, w zależności od typu pakietu wyrówanej do 32 bitów. Kilka pakietów może być szeregowo łączonych tworząc tak zwany złożony pakiet RTP, umieszczany w pakiecie warstwy niższej. Nie ma żadnego konkretnego wymogu na wielkosc pakietu złożonego, gdyż jest ona kontrolowana przez protokół transportowy. Każdy pakiet wchodzący w skład pakietu złożonego jest analizowany niezależnie od innych, stad kolejność i kombinacja pakietów nie są istotne. Tym niemniej aby spełnić wymaganie realizowane przez protokół na strukturę pakietu złożonego zostały nałożone następujące ograniczenia:
  • SR lub RR musza byc wysylane w kazdym pakiecie zlozonym, tak aby statystyki odbioru byly jak najbardziej dokladne
  • SDES z parametrem CNAME musi być wysylany w kazym pakieci zlozonym, tak aby odbiorca jak najszyciej otrzymal informacje o nadawcy
  • liczba pakietów wyslana w pierwszym pakiecie zlozonym powinna byc jak najmniejsza (2) tak aby liczba stalych bitów byla jak najwieksza i prawdopodobienstwo walidacji pakietu najwieksze

Stad tez struktura pakietu zlozonego musi zawierac conajmniej dwa pakiety o nastepujacej formie:

random encryption prefix: losowy 32-bitowy integer
|
|[--------- packet --------][---------- packet ----------][-packet-]
|
|                receiver            chunk        chunk
V                reports           item  item   item  item
--------------------------------------------------------------------
R[SR #sendinfo #site1#site2][SDES #CNAME PHONE #CNAME LOC][BYE##why]
--------------------------------------------------------------------
|                                                                  |
|<-----------------------  compound packet ----------------------->|
|<--------------------------  UDP packet ------------------------->|

#: SSRC/CSRC identifier
  • Encryption prefix – jesli pakiet zlozony jest szyforowany jest poprzedzany 32 bitową wartościa calkowita
  • SR lub RR – zawsze pierwszy pakiet w pakiecie zlozonym to SR lub RR nawet jesli zadne dane nie byly jeszcze wyslane
  • Dodatkowe RR – jesli liczba zrodel dla ktorych generowane sa statystyki przewyzsza 31 i nie moga byc umieszczone w jednym RR lub SS sa one umieszczane w dodatkowych pakietach RR
  • SDES – w kazdym pakiecie zlozonym musi byc dolaczony pakiet zawierajacy parametr CNAME inne parametry sa umieszczane w zalezności od aplikacji
  • BYE lub APP – pozostale pakiety moga sie pojawiac w dowolnej ilosci i kolejnosci z tym wyjatkiem ze pakiet BYE zawierajacy SSRC/CSRC musi byc ostatni
Kazdy uczestnik powinnien wysylac tylko jeden pakiet zlozony w trakcie okresu raportowania aby oszacowanie pasma bylo precyzyjniejsze. Jesli ilosc dodatkowych pakietow RR nie miesci sie w MTU nalezy ograniczyc ich ilosc i przeslac w nastepnej turze, tak by wszystkie zrodla byly raportowane.

Czestotliwosci RTCP

RTP zostalo tak zaprojektowane aby umozliwiac regulowanie ruchu kontrolnego w zaleznosci o ilosci uczestnikow i przyjetej charakterystyki lacza. Z kazda sesja danych RTP zwiazane jest maksymalne dopuszczalne pasmo sesji (session bandwidth) bedace agregacja danych poszczegolnych uczestnikow. Mechanizm doboru pasma sesji moze byc praktycznie dowolny ale najczesniej przyjmuje sie jego wartosc jako nominalna sume pasm zajmowanych przez maksymalna liczbe jednoczesnie aktywnych uczestnikow. Wartosc pasma sesji najczesciej ustalana jest przez warstwe aplikacji odpowiedzialna za zarzadzanie sesja przy czym najczesciej wartosc domyslna ustalana jest jako pasmo odpowiadajace jednemu aktywnemu uzytkownikowi. Wszyscy uczestnicy sesji musza uzywac tego samego pasma tak aby okres retransmisji RTCP byl taki sam. Warto pamietac ze w trakcie obliczania utylizacji dostepnego pasma brane sa pod uwage tez protokoly transportowe (UDP i IP) ale warstwa lacza danych juz nie gdyz te sie od siebie różnia. Ruch kontrolny jest ograniczany zarówno z góry jak i z dołu. Z góry jako czastkowa wartość calkowitego dostepnego pasma (norma 5%) lub jako wartość ilościowa. Z dolu natomiast ustala sie minimalna wartość tak aby nie generować nadmiernego ruchu (norma 5s), istnieja przypadki kiedy ta wartosc moze byc jeszcze bardziej zredukowana i odwrotnie proporcjonalna do dostepnego pasma. Zaleca sie rowniez aby z posrod calego ruchu RTCP, 1/4 byla przypisana do aktywnych uczestnikow, tak aby nowo dolaczajacy sie uzytkownicy szybko dowiadywali sie aktywnych CNAME. Algorytm oblicza czestotliowsci wysylania pakietów zlozonych tak aby dostępne pasmo na ruch kontrolny było równie rozdzielone pomiedzy uczestników. Wyznaczona czestotliwosc skaluje sie liniowe w stosunku do liczby uczestników, co zapewnia stała wartość ruchu kontrolnego. Aby uniknąc pelnej synchronizacji kazdy z uczestnikow posluguje sie lekka wariacja okresu wysylania RTCP oraz losowym opoznienieniem dla pierwszego wysylanego pakietu zlozonego. Dodatkowo obslugiwane sa mechanizmy obslugujace sytuacje wyjatkowe kiedy wielu uczestnikow jednoczesnie dolacza lub opuszcza sesje.

Ilosc Uczestnikow

Wyznaczanie czestotliwosci RTCP bazuje na znajomosci oszacowanej liczby uczestnikow. Uczestnik okreslany jest jako nowy gdy w sesji pojawi sie ruch z nowym identyfikatorem SSRC lub CSRC. Istnieje możliwosc przyjecia ze musi byc zarejstrowanych kilka pakietow by uznac ze pojawil sie nowy uczestnik lub ze musi zostac odebrany pakiet SDES z nowym CNAME. Uczestnika uwaza sie za usunietego gdy wysyla pakiet BYE lub przez okreslony czas nie wysyla pakietow.

Zasady Wysylania i Odbierania pakietow RTCP

Aby zrealizowac powyzsze zalozenia kazdy uzytkownik musi lokalnie przechowywac szereg informacji zwiazanych z realizowana sesja:

  • tp – czas ostatniej transmisji
  • tc- obecny czas
  • tn – czas nastepnej transmisji
  • pmembers – oszacowana liczba uczestnikow podczas podczas ostatniej transmisji
  • members – aktualna oszacowana liczba uczestnikow
  • senders – aktualna oszacowana liczba aktywnych uczestnikow
  • rtcp_bw – pasmo przydzielone dla calego ruchu RTCP wszystkich uczestnikow
  • we_sent – flaga informujaca czy od ostatniego raportu uczestnik wyslal dane
  • avg_rtcp_size – sredni rozmiar wyslanych i odebranych pakietow przez uzytkownika
  • initial – ustawiona na true gdy uzytkownik nie wyslal jeszcze zadnego pakietu RTCP
W trakcie inicjalizacji aplikacji parametry ustawiane sa na wartosci domyslne. Wartosc okresu nadawania wiadomosci kontrolnych jest obliczana na podstawie powyzej wymienionych parameterow. Procedura w efekcie daje przedzial ktory jest losowy i przydziela minimum 1/4 calego dostepnego pasma uzytkownikom aktywnym. Jesli uzytkoników aktywnych jest wiecej niż 1/4 wszystkich uzytkownikow dostepne pasmo jest dytrybuowane po rowno do wszystkich uczestników. Po otrzymaniu pakietu RTP lub RTCP od uczesnika, ktorego SSRC nie jest obecne w tablicy uczestników, jest on dodawany do listy i liczba uczestnikow jest aktualizowana. Kiedy pakiet RTP jest od uczestnika ktory nie znajduje sie na liscie aktywnych uczestnikow jest on do niej dodawany i ich liczba jest aktualizowana. Jak zawsze przy kazdym odebranym i wyslanym pakiecie wartosc avg_rtcp_size jest aktualizowana. Gdy uczestnik odbiera pakiet BYE sprawdza czy na liscie uczestników lub aktywnych uczestników znajduje nadawca pakietu, jesli tak, jest on z niej usuwany, aktualizowane sa parametry oraz czas wyslania nastepnego zlozonego pakietu RTCP. Przynajmniej raz na jeden okres przesylania pakietu kontrolnego uczestnik weryfikuje czy na którejś z list nie nastapil timeout dla danego SSRC. Kiedy uczestnik chce opuscic sesje moze ale nie musi wyslac pakiet BYE, jesli tego nie zrobi nastapi timeout. Jesli liczba uzytkownikow jest mala (zalecane 50) moze wyslac pakiet od razu, w przeciwnym wypadku stosuje mechanizm zapobiegajacy masowemu opuszczaniu sesji przez duza liczbe uczestnikow.

Pakiety SR i RR

W oparciu o pakiety RR odbiorcy informuja o jakosci odbieranych danych, jeśli odbiorca jest uczestnikiem aktywnym i wysyłał dane od ostatniego raportu wykorzystuje pakiet SR zawierajacy dodatkowe informacje o nadawcy. W kazdym pakiecie SR i RR znajduje sie po jednym bloku raportujacym skojarzonym z jednym źródłem synchronizacji. Jeśli zródeł jest wiecej niż 31 powinny zostać umieszczone w kolejnych pakietach RR.
SR składa sie z trzech sekcji obowiazkowych: nagłówka, informacji o nadawcy, listy bloków raportujacych i czwartej opcjonalnej dedykowanej dla konkretnego profilu. opcjonalna cześć jest wykorzystywana gdy profil RTP wymaga przesylania dodatkowych informacji pomiedzy stronami.
        0                   1                   2                   3
        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
header |V=2|P|    RC   |   PT=SR=200   |             length            |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                         SSRC of sender                        |
       +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
sender |              NTP timestamp, most significant word             |
info   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |             NTP timestamp, least significant word             |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                         RTP timestamp                         |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                     sender's packet count                     |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                      sender's octet count                     |
       +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
report |                 SSRC_1 (SSRC of first source)                 |
block  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  1    | fraction lost |       cumulative number of packets lost       |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |           extended highest sequence number received           |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                      interarrival jitter                      |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                         last SR (LSR)                         |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                   delay since last SR (DLSR)                  |
       +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
report |                 SSRC_2 (SSRC of second source)                |
block  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  2    :                               ...                             :
       +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
       |                  profile-specific extensions                  |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  • wersja (V): 2 bity – identyfikuje wersje, tak samo jak RTP 2
  • padding (P): 1 bit – wskazuje czy koniec pakietu jest uzupelniony zerami, jesli tak ostatni oktet wskazuje na liczbe oktetow do pominiecia
  • reception report count (RC): 5 bitów – liczba blokow raportujacych w tym pakiecie
  • packet type (PT): 8 bitów – indentyfikuej pakiet RTCP SR (stala wartosc 200)
  • length: 16 bitów – dlugosc pakietu w 32 bitowych słowach właczając nagłówek i wyrównanie
  • SSRC: 32 bity – identyfikator SSRC zródla pakietu SR
  • NTP timestamp: 64 bity – zegarowy czas wyslania pakietu
  • RTP timestamp: 32 bity – okresowy czas wyslania pakietu
  • sender’s packet count: 32 bity – calkowita liczba pakietow RTP wyslanych przez uczest
  • SSRC_n (source identifier): 32 bity – identyfikator SSRC dla zrodla ktorego dotyczy raport
  • fraction lost: 8 bitów – stosunek pakietow odebranych do pakietow spodziewanych RTP
  • cumulative number of packets lost: 24 bity – calkowita liczba wszystkich zgóbionych pakietów RTP
  • xtended highest sequence number received: 32 bity – najwieszky numer sekwencyjny odebranego pakietu
  • interarrival jitter: 32 bity – roznica pomiedzy odstepem w wysylaniu kolejnych pakietow
  • last SR timestamp (LSR): 32 bity – srodkowe 32 bity otrzymane w SR od nadawcy
  • delay since last SR (DLSR): 32 bity – czas pomiedzy odbiorem pakietu SR od nadawcy a nadaniem tego bloku raportujacego
Struktura pakietu RR jest taka sama jak pakietu SR, z tą różnicą że pakiet RR nie zawiera czesci informacyjnej o nadawcy a pole typu pakietu zawiera wartosc 201:
        0                   1                   2                   3
        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
header |V=2|P|    RC   |   PT=RR=201   |             length            |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                     SSRC of packet sender                     |
       +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
report |                 SSRC_1 (SSRC of first source)                 |
block  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  1    | fraction lost |       cumulative number of packets lost       |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |           extended highest sequence number received           |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                      interarrival jitter                      |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                         last SR (LSR)                         |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                   delay since last SR (DLSR)                  |
       +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
report |                 SSRC_2 (SSRC of second source)                |
block  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  2    :                               ...                             :
       +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
       |                  profile-specific extensions                  |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Po otrzymaniu raportu w postaci pakietu SR lub RR nadawca moze zmodyfikować na jego podstawie charakterysytke sesji, określić zakres wystepujących problemów, określić skutecznosc w dostarczaniu raportow itp. Dane raportujace moga byc rowniez agregowane przez aplikacje monitorujace nadzorujace wydajnosc sieci.

Pakiety SDES

Pakiet SDES posiada trzy poziomową strukture, w której skład wchodzi nagłówek, zero lub wiecej fragmentów zawierających atrybuty opisujące zródło identyfikowane w danym fragmencie. Każdy fragment zawiera indentyfikator SSRC/CSRC oraz listę atrybótów. Każdy atrybut zawiera 2 8-śmio bitowe pola wskazujace na jego typ oraz dlugość oraz sam tekst, gdzie tekst nie może być dłuższy niż 255 oktetów
        0                   1                   2                   3
        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
header |V=2|P|    SC   |  PT=SDES=202  |             length            |
       +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
chunk  |                          SSRC/CSRC_1                          |
  1    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                           SDES items                          |
       |                              ...                              |
       +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
chunk  |                          SSRC/CSRC_2                          |
  2    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                           SDES items                          |
       |                              ...                              |
       +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
  • version (V) – wersja, padding (P) – dopełnienie, length – dlugość
  • packet type (PT): 8 bitów – typ pakietu (202)
  • source count (SC): 5 bitów – liczba fragmentów w pakiecie

autor: Tomasz Zieleniewski

You May Also Like

Log4j and MDC in Grails

Log4j provides very useful feature: MDC - mapped diagnostic context. It can be used to store data in context of current thread. It may sound scary a bit but idea is simple.

My post is based on post http://burtbeckwith.com/blog/?p=521 from Burt Beckwith's excellent blog, it's definitely worth checking if you are interested in Grails.

Short background story...


Suppose we want to do logging our brand new shopping system and we want to have in each log customer's shopping basket number. And our system can be used at once by many users who can perform many transactions, actions like adding items and so on. How can we achieve that? Of course we can add basket number in every place where we do some logging but this task would be boring and error-prone. 

Instead of this we can use MDC to store variable with basket number in map. 

In fact MDC can be treated as map of custom values for current thread that can be used by logger. 


How to do that with Grails?


Using MDC with Grails is quite simple. All we need to do is to create our own custom filter which works for given urls and puts our data in MDC.

Filters in Grails are classes in directory grails-app/conf/* which names end with *Filters.groovy postfix. We can create this class manually or use Grails command: 
grails create-filters info.rnowak.App.Basket

In result class named BasketFilters will be created in grails-app/conf/info/rnowak/UberApp.

Initially filter class looks a little bit empty:
class BasketFilters {
def filters = {
all(controller:'*', action:'*') {
before = {

}
after = { Map model ->

}
afterView = { Exception e ->

}
}
}
}
All we need to do is fill empty closures, modify filter properties and put some data into MDC.

all is the general name of our filter, as class BasketFilters (plural!) can contain many various filters. You can name it whatever you want, for this post let assume it will be named basketFilter

Another thing is change of filter parameters. According to official documentation (link) we can customize our filter in many ways. You can specify controller to be filtered, its actions, filtered urls and so on. In our example you can stay with default option where filter is applied to every action of every controller. If you are interested in filtering only some urls, use uri parameter with expression describing desired urls to be filtered.

Three closures that are already defined in template have their function and they are started in these conditions:

  • before - as name says, it is executed before filtered action takes place
  • after - similarly, it is called after the action
  • afterView - called after rendering of the actions view
Ok, so now we know what are these mysterious methods and when they are called. But what can be done within them? In official Grails docs (link again) under section 7.6.3 there is a list of properties that are available to use in filter.

With that knowledge, we can proceed to implementing filter.

Putting something into MDC in filter


What we want to do is quite easy: we want to retrieve basket number from parameters and put it into MDC in our filter:
class BasketFilters {
def filters = {
basketFilter(controller:'*', action:'*') {
before = {
MDC.put("basketNumber", params.basketNumber ?: "")
}
after = { Map model ->
MDC.remove("basketNumber")
}
}
}
}

We retrieve basket number from Grails params map and then we put in map under specified key ("basketNumber" in this case), which will be later used in logger conversion pattern. It is important to remove custom value after processing of action to avoid leaks.

So we are putting something into MDC. But how make use of it in logs?


We can refer to custom data in MDC in conversion patter using syntax: %X{key}, where key is our key we used in filter to put data, like:
def conversionPattern = "%d{yyyy-MM-dd HH:mm:ss} %-5p %t [%c{1}] %X{basketNumber} - %m%n"


And that's it :) We've put custom data in log4j MDC and successfully used it in logs to display interesting values.