{"id":2547,"date":"2019-03-23T10:37:06","date_gmt":"2019-03-23T07:37:06","guid":{"rendered":"https:\/\/gokhan-gokalp.com\/?p=2547"},"modified":"2019-03-23T10:42:59","modified_gmt":"2019-03-23T07:42:59","slug":"logging-api-requests-and-responses-to-graylog-over-azure-api-management-using-azure-functions","status":"publish","type":"post","link":"https:\/\/gokhan-gokalp.com\/tr\/logging-api-requests-and-responses-to-graylog-over-azure-api-management-using-azure-functions\/","title":{"rendered":"API Request ve Response&#8217;lar\u0131n\u0131 Azure API Management \u00fczerinden Azure Funtions Kullanarak GrayLog&#8217;a Loglama"},"content":{"rendered":"<p>Sizlerinde bildi\u011fi gibi hemen hemen her backend application&#8217;\u0131n\u0131n sahip olmas\u0131 gereken en temel \u00f6zelliklerden birisi, <em>request<\/em> ve <em>response<\/em>&#8216;lar\u0131n <strong>log<\/strong>&#8216;lanmas\u0131d\u0131r. \u00d6zellikle \u00e7oklu\u00a0<em>API<\/em> kullan\u0131m\u0131n\u0131n s\u00f6z konusu oldu\u011fu ortamlarda, &#8220;<em>nice-to-have<\/em>&#8221; durumundan &#8220;<em>must-have<\/em>&#8221; durumuna ge\u00e7i\u015f yapan temel bir \u00f6zellik.<a href=\"\/wp-content\/uploads\/2019\/03\/graylog-azure-functions-api-management.jpg\"><img decoding=\"async\" class=\"aligncenter wp-image-2553 lazyload\" data-src=\"\/wp-content\/uploads\/2019\/03\/graylog-azure-functions-api-management.jpg\" alt=\"\" width=\"742\" height=\"494\" data-srcset=\"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2019\/03\/graylog-azure-functions-api-management.jpg 1280w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2019\/03\/graylog-azure-functions-api-management-300x200.jpg 300w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2019\/03\/graylog-azure-functions-api-management-768x512.jpg 768w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2019\/03\/graylog-azure-functions-api-management-1024x682.jpg 1024w\" data-sizes=\"(max-width: 742px) 100vw, 742px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 742px; --smush-placeholder-aspect-ratio: 742\/494;\" \/><\/a><\/p>\n<p>\u00c7\u00fcnk\u00fc \u00f6yle bir zaman geliyor ki, <em>API<\/em>&#8216;\u0131\u00a0call eden bir client&#8217;a, g\u00f6nderdi\u011fi request&#8217;in hatal\u0131 parametreler i\u00e7erdi\u011fini g\u00f6sterebilmeniz gerekiyor.<\/p>\n<blockquote><p>K\u0131sacas\u0131, daha iyi bir &#8220;<strong>iz s\u00fcrebilmek<\/strong>&#8221; ad\u0131na <em>API&#8217;<\/em>lar\u0131m\u0131za kazand\u0131rmam\u0131z gereken bir \u00f6zellik.<\/p><\/blockquote>\n<h2>Hikaye<\/h2>\n<p>K\u0131sa bir s\u00fcre i\u00e7erisinde, t\u00fcm <em>API<\/em> request ve response&#8217;lar\u0131n\u0131 log&#8217;lama gereksinimimiz olu\u015ftu. Evet, bunu ger\u00e7ekle\u015ftirebilmenin bir \u00e7ok y\u00f6ntemi mevcut. \u00d6rne\u011fin her <em>API<\/em>&#8216;\u0131n i\u00e7erisinde bir middleware yazarak, request ve response&#8217;lar\u0131 log&#8217;layabilmek gibi. Tabi hepsinin de ayr\u0131 bir tradeoff&#8217;u mevcut.<\/p>\n<p>Bir middleware yazd\u0131k diyelim, hangi <em>API&#8217;<\/em>a kim implemente edecek? Performans&#8217;a k\u00f6t\u00fc bir \u015fekilde yan etki edecek mi? Tabi, en \u00f6nemlisi de <strong>vakit<\/strong>.<\/p>\n<p>Bu makale kapsam\u0131nda ise, request ve response&#8217;lar\u0131 log&#8217;layabilme gereksinimimizi &#8220;quick-win&#8221; bir \u00e7\u00f6z\u00fcm olarak nas\u0131l ger\u00e7ekle\u015ftirdi\u011fime de\u011finmeye \u00e7al\u0131\u015faca\u011f\u0131m.<\/p>\n<h2>Peki<\/h2>\n<p>\u00c7\u00f6z\u00fcm\u00fcn daha net anla\u015f\u0131labilmesi i\u00e7in \u00f6ncelikle sistemimiz hakk\u0131nda sizlere k\u0131saca bir bilgi vermek istiyorum. \u00dczerinde \u00e7al\u0131\u015ft\u0131\u011f\u0131m proje, tamamen <em>cloud-native<\/em> ve <em>microservice<\/em> yakla\u015f\u0131m\u0131 ile design edilmi\u015f bir sistem&#8217;e sahip. Application&#8217;lar <em>Azure Kubernetes Service<\/em> \u00fczerinde ve t\u00fcm <em>API<\/em>&#8216;lar\u0131m\u0131z\u0131\u00a0<em>Azure API Management<\/em> vas\u0131tas\u0131yla y\u00f6netiyoruz.<\/p>\n<p><a href=\"\/wp-content\/uploads\/2019\/03\/microservice-architecture-azure-cloud.jpg\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-2554 lazyload\" data-src=\"\/wp-content\/uploads\/2019\/03\/microservice-architecture-azure-cloud.jpg\" alt=\"\" width=\"2746\" height=\"1806\" data-srcset=\"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2019\/03\/microservice-architecture-azure-cloud.jpg 2746w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2019\/03\/microservice-architecture-azure-cloud-300x197.jpg 300w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2019\/03\/microservice-architecture-azure-cloud-768x505.jpg 768w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2019\/03\/microservice-architecture-azure-cloud-1024x673.jpg 1024w\" data-sizes=\"(max-width: 2746px) 100vw, 2746px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 2746px; --smush-placeholder-aspect-ratio: 2746\/1806;\" \/><\/a><\/p>\n<p><em>Azure API Management<\/em>, distributed olarak design etti\u011fimiz sistemde bizim i\u00e7in olmazsa olmaz par\u00e7alardan bir tanesi. Bu makale kapsam\u0131nda, microservice mimarisinde <em>API Gateway<\/em> kullan\u0131m\u0131n\u0131n faydalar\u0131n\u0131n detay\u0131na \u00e7ok fazla girmeyece\u011fim.<\/p>\n<p>Fakat, <em>API Gateway<\/em> kullan\u0131m\u0131n\u0131n bana &#8220;quick-win&#8221; bir \u00e7\u00f6z\u00fcm \u00fcretebilmemi sa\u011flayan noktalar\u0131ndan bir tanesine de\u011finmek istiyorum.<\/p>\n<blockquote><p><em>API Gateway<\/em>, sisteme &#8220;tek bir giri\u015f noktas\u0131&#8221; ve uniform bir experience olu\u015fturabilmemize olanak sa\u011flamaktad\u0131r.<\/p><\/blockquote>\n<p>Dolay\u0131s\u0131yla routing i\u015fleminin d\u0131\u015f\u0131nda, request ve response&#8217;lar \u00fczerinde de istedi\u011fimiz manupilasyonlar\u0131 yapabilmemize olanak tan\u0131maktad\u0131r.<\/p>\n<p>Hal buyken, neden request ve response log&#8217;lama i\u015flemlerini tek tek her bir <em>API<\/em> i\u00e7erisinden ger\u00e7ekle\u015ftireyim? De\u011fil mi?<\/p>\n<p><a href=\"\/wp-content\/uploads\/2019\/03\/azure-api-logging.jpg\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-2555 lazyload\" data-src=\"\/wp-content\/uploads\/2019\/03\/azure-api-logging.jpg\" alt=\"\" width=\"825\" height=\"464\" data-srcset=\"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2019\/03\/azure-api-logging.jpg 825w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2019\/03\/azure-api-logging-300x169.jpg 300w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2019\/03\/azure-api-logging-768x432.jpg 768w\" data-sizes=\"(max-width: 825px) 100vw, 825px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 825px; --smush-placeholder-aspect-ratio: 825\/464;\" \/><\/a><\/p>\n<p>Bir \u00e7ok <em>API<\/em> Gateway&#8217;in de sahip oldu\u011fu gibi, <em>Azure API Management<\/em>&#8216;da bir logging policy&#8217;sine sahip. Bu policy&#8217;leri kullanarak, <strong>platform-independet\u00a0<\/strong>ve <strong>merkezi<\/strong> bir logging i\u015flemi ger\u00e7ekle\u015ftirebilmek m\u00fcmk\u00fcn oluyor.<\/p>\n<h2><b>Peki, Nas\u0131l?<\/b><\/h2>\n<p>Bu noktada, bir ka\u00e7 farkl\u0131 ad\u0131m\u0131 s\u0131ras\u0131yla izleyece\u011fiz:<\/p>\n<ol>\n<li><em>Azure Event Hub<\/em>\u00a0olu\u015fturulmas\u0131<\/li>\n<li><em>Azure API Management<\/em> Logger olu\u015fturulmas\u0131<\/li>\n<li><em>Azure API Management<\/em> Log Policy&#8217;sinin configure edilmesi<\/li>\n<li><em>Azure Event Hub<\/em>\u00a0triggered <em>Azure Function<\/em> olu\u015fturulmas\u0131 ve <em>GrayLog<\/em>&#8216;a log g\u00f6nderilmesi<\/li>\n<li>Olu\u015fturulan <em>Azure Function<\/em>&#8216;\u0131n deploy edilmesi<\/li>\n<\/ol>\n<h4>1. <em>Azure Event Hub<\/em>\u00a0olu\u015fturulmas\u0131<\/h4>\n<p><em>Azure API Management<\/em>&#8216;da &#8220;<em>Log to EventHub<\/em>&#8221; isminde bir advanced policy&#8217;e sahibiz. Bu policy ile performance impact&#8217;ini minimize ederek (performance impact&#8217;ini de g\u00f6z \u00f6n\u00fcnde bulundurmal\u0131y\u0131m), t\u00fcm log&#8217;lar\u0131 <em>Event Hub<\/em>&#8216;a g\u00f6nderebilir ve daha sonra istedi\u011fimiz gibi i\u015fleyebilir, kaydedebiliriz.<\/p>\n<p>E\u011fer hali haz\u0131rda bir\u00a0<em>Event Hub<\/em>\u00a0kullanm\u0131yorsan\u0131z, bir <em>Event Hub<\/em>\u00a0namespace&#8217;i ve instance&#8217;\u0131na ihtiyac\u0131n\u0131z var demektir.<\/p>\n<blockquote><p><em>Azure Event Hub<\/em>\u00a0saniyede milyonlarca event&#8217;i al\u0131p, i\u015fleyebilme yetene\u011fine sahip bir event ingestion service&#8217;idir.<\/p><\/blockquote>\n<p>Hemen olu\u015fturabilmek i\u00e7in <em><a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/event-hubs\/event-hubs-create\" target=\"_blank\" rel=\"noopener\">buradaki<\/a><\/em> ad\u0131mlar\u0131 takip edebiliriniz.<\/p>\n<p><em>Event Hub<\/em>\u00a0olu\u015fturma ad\u0131mlar\u0131n\u0131 tamamlad\u0131ktan sonra, <em>Azure API Management<\/em> i\u00e7erisinden <em>Event Hub<\/em>&#8216;\u0131 kullanabilmemiz i\u00e7in bir <em>shared access policy<\/em>&#8216;e ihtiyac\u0131m\u0131z var. Bu policy&#8217;i elde edebilmek i\u00e7in olu\u015fturmu\u015f oldu\u011funuz <em>Event Hub<\/em>\u00a0entity&#8217;sine t\u0131klayarak detaylar\u0131na girelim.<\/p>\n<p><a href=\"\/wp-content\/uploads\/2019\/03\/event-hub-detail.jpg\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-2558 lazyload\" data-src=\"\/wp-content\/uploads\/2019\/03\/event-hub-detail.jpg\" alt=\"\" width=\"1740\" height=\"732\" data-srcset=\"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2019\/03\/event-hub-detail.jpg 1740w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2019\/03\/event-hub-detail-300x126.jpg 300w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2019\/03\/event-hub-detail-768x323.jpg 768w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2019\/03\/event-hub-detail-1024x431.jpg 1024w\" data-sizes=\"(max-width: 1740px) 100vw, 1740px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 1740px; --smush-placeholder-aspect-ratio: 1740\/732;\" \/><\/a><\/p>\n<p>Ard\u0131ndan yukar\u0131daki gibi sol tarafda bulunan &#8220;<em>Shared access policies<\/em>&#8221; sekmesine t\u0131klayal\u0131m.<\/p>\n<p><a href=\"\/wp-content\/uploads\/2019\/03\/event-hub-shared-access-policy.jpg\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-2559 lazyload\" data-src=\"\/wp-content\/uploads\/2019\/03\/event-hub-shared-access-policy.jpg\" alt=\"\" width=\"1762\" height=\"800\" data-srcset=\"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2019\/03\/event-hub-shared-access-policy.jpg 1762w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2019\/03\/event-hub-shared-access-policy-300x136.jpg 300w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2019\/03\/event-hub-shared-access-policy-768x349.jpg 768w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2019\/03\/event-hub-shared-access-policy-1024x465.jpg 1024w\" data-sizes=\"(max-width: 1762px) 100vw, 1762px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 1762px; --smush-placeholder-aspect-ratio: 1762\/800;\" \/><\/a><\/p>\n<p>\u015eimdi policy tan\u0131mlayabilmek i\u00e7in &#8220;<em>Add<\/em>&#8221; butonuna basal\u0131m ve tan\u0131mlama i\u015flemini ger\u00e7ekle\u015ftirelim. Ben &#8220;<em>AzureAPIManagement<\/em>&#8221; isminde bir policy tan\u0131mlad\u0131m. Olu\u015fturma i\u015fleminin ard\u0131ndan, yukar\u0131da g\u00f6rd\u00fc\u011f\u00fcm\u00fcz gibi <em>Event Hub<\/em> instance&#8217;\u0131n\u0131n connection string bilgilerine eri\u015febilece\u011fiz.<\/p>\n<h4>2. <em>Azure API Management<\/em> Logger olu\u015fturulmas\u0131<\/h4>\n<p><em>Event Hub<\/em> ad\u0131mlar\u0131n\u0131 tamamlad\u0131k. \u015eimdi ise <em>Azure API Management<\/em> i\u00e7erisinde bir <strong>logger<\/strong>&#8216;a ihtiyac\u0131m\u0131z var. Logger&#8217;\u0131 olu\u015fturma i\u015flemini <em>Azure API Management REST API<\/em>&#8216;\u0131 \u00fczerinden ger\u00e7ekle\u015ftirece\u011fiz.<\/p>\n<p>Logger olu\u015fturma i\u015flemine ba\u015flamadan \u00f6nce, <em>Azure API Management<\/em> servisindeki <em>REST API<\/em> hizmetini enable etmemiz gerekmektedir. Enable edebilmek i\u00e7in\u00a0<em>Azure API Management<\/em> instance&#8217;\u0131 i\u00e7erisinden, a\u015fa\u011f\u0131daki gibi &#8220;<em>Management API<\/em>&#8221; sekmesine girerek &#8220;<em>Enable API Management REST API<\/em>&#8221; checkbox&#8217;\u0131n\u0131 i\u015faretlememiz yeterli olacakt\u0131r.<\/p>\n<p><a href=\"\/wp-content\/uploads\/2019\/03\/api-management-rest.jpg\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-2562 lazyload\" data-src=\"\/wp-content\/uploads\/2019\/03\/api-management-rest.jpg\" alt=\"\" width=\"1786\" height=\"1646\" data-srcset=\"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2019\/03\/api-management-rest.jpg 1786w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2019\/03\/api-management-rest-300x276.jpg 300w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2019\/03\/api-management-rest-768x708.jpg 768w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2019\/03\/api-management-rest-1024x944.jpg 1024w\" data-sizes=\"(max-width: 1786px) 100vw, 1786px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 1786px; --smush-placeholder-aspect-ratio: 1786\/1646;\" \/><\/a><\/p>\n<p><em>REST API<\/em>&#8216;\u0131 enable ettikten sonra, a\u015fa\u011f\u0131daki &#8220;<em>Accesss token<\/em>&#8221; b\u00f6l\u00fcm\u00fcndeki &#8220;<em>Generate<\/em>&#8221; butonuna basarak bir access token elde edelim.<\/p>\n<p>Art\u0131k bir logger olu\u015fturabiliriz. Logger olu\u015fturabilmek i\u00e7in a\u015fa\u011f\u0131daki <em>URL<\/em>&#8216;e bir <em>HTTP PUT<\/em> request&#8217;i g\u00f6ndermemiz gerekmektedir.<\/p>\n<p><em>https:\/\/my-api-management. management.azure-api.net\/loggers\/my-logger?api-version=2018-01-01<\/em><\/p>\n<blockquote><p>NOT: {<em>my-api-management<\/em>} ve {<em>my-logger<\/em>} parametrelerini, kendi service name&#8217;leriniz ile de\u011fi\u015ftirmeyi unutmay\u0131n.<\/p><\/blockquote>\n<p>Header&#8217;a ise eklememiz gereken bir ka\u00e7 parametre bulunmaktad\u0131r.<\/p>\n<ul>\n<li><em>Content-Type<\/em> : application\/json<\/li>\n<li><em>Authorization<\/em> : &#8220;API Management <em>REST API<\/em> access token&#8221;<\/li>\n<\/ul>\n<p>ve payload ise a\u015fa\u011f\u0131daki gibi olmal\u0131:<\/p>\n<pre class=\"lang:default decode:true \">{\r\n  \"loggerType\" : \"AzureEventHub\",\r\n  \"description\" : \"My event hub logger\",\r\n  \"credentials\" : {\r\n    \"name\" : \"my-log-hub\",\r\n    \"connectionString\" : \"Endpoint=my-log-hub sender connection string\"\r\n    }\r\n}<\/pre>\n<p><a href=\"\/wp-content\/uploads\/2019\/03\/logger-created.jpg\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-2563 lazyload\" data-src=\"\/wp-content\/uploads\/2019\/03\/logger-created.jpg\" alt=\"\" width=\"1912\" height=\"1152\" data-srcset=\"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2019\/03\/logger-created.jpg 1912w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2019\/03\/logger-created-300x181.jpg 300w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2019\/03\/logger-created-768x463.jpg 768w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2019\/03\/logger-created-1024x617.jpg 1024w\" data-sizes=\"(max-width: 1912px) 100vw, 1912px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 1912px; --smush-placeholder-aspect-ratio: 1912\/1152;\" \/><\/a><\/p>\n<p><em>Event Hub<\/em> logger art\u0131k kullan\u0131ma haz\u0131r. Buradaki &#8220;<em>my-logger<\/em>&#8221; olan logger name&#8217;ini not alal\u0131m. Daha sonra logger policy&#8217;sini tan\u0131mlarken kullanaca\u011f\u0131z.<\/p>\n<h4>3.<em> Azure API Management<\/em> Log Policy&#8217;sinin configure edilmesi<\/h4>\n<p>Logger policy&#8217;sini tan\u0131mlayabilmek i\u00e7in ilgili <em>Azure API Management<\/em> instance&#8217;\u0131na girelim ve sol men\u00fcdeki &#8220;<em>APIs<\/em>&#8221; sekmesine t\u0131klayal\u0131m. Ard\u0131ndan a\u015fa\u011f\u0131daki gibi &#8220;<em>All APIs<\/em>&#8221; b\u00f6l\u00fcm\u00fcne ge\u00e7elim.<\/p>\n<p><a href=\"\/wp-content\/uploads\/2019\/03\/azure-api-management-policies.jpg\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-2565 lazyload\" data-src=\"\/wp-content\/uploads\/2019\/03\/azure-api-management-policies.jpg\" alt=\"\" width=\"2252\" height=\"1016\" data-srcset=\"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2019\/03\/azure-api-management-policies.jpg 2252w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2019\/03\/azure-api-management-policies-300x135.jpg 300w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2019\/03\/azure-api-management-policies-768x346.jpg 768w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2019\/03\/azure-api-management-policies-1024x462.jpg 1024w\" data-sizes=\"(max-width: 2252px) 100vw, 2252px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 2252px; --smush-placeholder-aspect-ratio: 2252\/1016;\" \/><\/a><\/p>\n<p>Burada yapmak istedi\u011fimiz \u015fey, t\u00fcm <em>API&#8217;<\/em>&#8216;ar\u0131m\u0131z i\u00e7in ge\u00e7erli olacak bir <em>Event Hub<\/em> logger eklemek. Bunu yapabilmek i\u00e7in &#8220;<em>inbound<\/em>&#8221; ve &#8220;<em>outbound<\/em>&#8221; processing k\u0131s\u0131mlar\u0131na bir &#8220;<em>Log to EventHub<\/em>&#8221; policy&#8217;si ekliyece\u011fiz.<\/p>\n<p>Policy ekleyebilmek i\u00e7in,\u00a0sa\u011f k\u0131s\u0131mdaki &#8220;<em>Policies<\/em>&#8221; ba\u015fl\u0131\u011f\u0131n\u0131n yan\u0131nda bulunan icon&#8217;a t\u0131klayal\u0131m ve code view ekran\u0131na ge\u00e7elim.<\/p>\n<p><a href=\"\/wp-content\/uploads\/2019\/03\/azure-api-management-policy-log.jpg\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-2567 lazyload\" data-src=\"\/wp-content\/uploads\/2019\/03\/azure-api-management-policy-log.jpg\" alt=\"\" width=\"2314\" height=\"786\" data-srcset=\"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2019\/03\/azure-api-management-policy-log.jpg 2314w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2019\/03\/azure-api-management-policy-log-300x102.jpg 300w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2019\/03\/azure-api-management-policy-log-768x261.jpg 768w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2019\/03\/azure-api-management-policy-log-1024x348.jpg 1024w\" data-sizes=\"(max-width: 2314px) 100vw, 2314px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 2314px; --smush-placeholder-aspect-ratio: 2314\/786;\" \/><\/a><\/p>\n<p>\u015eimdi &#8220;<em>inbound<\/em>&#8221; ve &#8220;<em>outbound<\/em>&#8221; tag&#8217;lerinin aras\u0131na, &#8220;<em>Advanced Policies<\/em>&#8221; alt\u0131ndaki &#8220;<em>Log to EventHub<\/em>&#8221; policy&#8217;sini ekleyelim ve a\u015fa\u011f\u0131daki gibi d\u00fczenleyelim.<\/p>\n<pre class=\"lang:default decode:true\">&lt;policies&gt;\r\n    &lt;inbound&gt;\r\n        &lt;set-variable name=\"message-id\" value=\"@(Guid.NewGuid())\" \/&gt;\r\n        &lt;log-to-eventhub logger-id=\"my-logger\" partition-id=\"1\"&gt;@{\r\n            var requestLine = string.Format(\"{0} {1} HTTP\/1.1\\r\\n\",\r\n                                                      context.Request.Method,\r\n                                                      context.Request.Url.Path + context.Request.Url.QueryString);\r\n\r\n            var body = context.Request.Body?.As&lt;string&gt;(true);\r\n            if (body != null &amp;&amp; body.Length &gt; 1024)\r\n            {\r\n                body = body.Substring(0, 1024);\r\n            }\r\n\r\n            var headers = context.Request.Headers\r\n                                .Where(h =&gt; h.Key != \"Authorization\" &amp;&amp; h.Key != \"Ocp-Apim-Subscription-Key\")\r\n                                .Select(h =&gt; string.Format(\"{0}: {1}\", h.Key, String.Join(\", \", h.Value)))\r\n                                .ToArray&lt;string&gt;();\r\n\r\n            var headerString = (headers.Any()) ? string.Join(\"\\r\\n\", headers) + \"\\r\\n\" : string.Empty;\r\n\r\n            return \"request:\"   + context.Variables[\"message-id\"] + \"\\n\"\r\n                                + requestLine + headerString + \"\\r\\n\" + body;\r\n        }&lt;\/log-to-eventhub&gt;\r\n    &lt;\/inbound&gt;\r\n    &lt;backend&gt;\r\n        &lt;forward-request \/&gt;\r\n    &lt;\/backend&gt;\r\n    &lt;outbound&gt;\r\n        &lt;log-to-eventhub logger-id=\"my-logger\" partition-id=\"1\"&gt;@{\r\n            var statusLine = string.Format(\"HTTP\/1.1 {0} {1}\\r\\n\",\r\n                                                context.Response.StatusCode,\r\n                                                context.Response.StatusReason);\r\n\r\n            var body = context.Response.Body?.As&lt;string&gt;(true);\r\n            if (body != null &amp;&amp; body.Length &gt; 1024)\r\n            {\r\n                body = body.Substring(0, 1024);\r\n            }\r\n\r\n            var headers = context.Response.Headers\r\n                                            .Select(h =&gt; string.Format(\"{0}: {1}\", h.Key, String.Join(\", \", h.Value)))\r\n                                            .ToArray&lt;string&gt;();\r\n\r\n            var headerString = (headers.Any()) ? string.Join(\"\\r\\n\", headers) + \"\\r\\n\" : string.Empty;\r\n\r\n            return \"response:\"  + context.Variables[\"message-id\"] + \"\\n\"\r\n                                + statusLine + headerString + \"\\r\\n\" + body;\r\n        }&lt;\/log-to-eventhub&gt;\r\n    &lt;\/outbound&gt;\r\n    &lt;on-error \/&gt;\r\n&lt;\/policies&gt;<\/pre>\n<p>Burada dikkat etmemiz gereken nokta &#8220;<em>logger-id<\/em>&#8221; parametresi. Bu parametreye value olarak,\u00a0<em>Event Hub<\/em> logger olu\u015ftururken belirledi\u011fimiz logger name&#8217;ini set ediyoruz. Ayr\u0131ca &#8220;<em>message-id<\/em>&#8221; variable&#8217;\u0131 ile de request ve response&#8217;lar\u0131 correlate ederek, <em>Event Hub<\/em>&#8216;a g\u00f6nderiyoruz.<\/p>\n<p>Bu arada,\u00a0<em>Azure API Management<\/em> i\u00e7erisinden <em>C#<\/em> based policy yazabilmek \u00e7ok g\u00fczel, de\u011fil mi?<\/p>\n<h4>4.<em> Azure Event Hub<\/em>\u00a0triggered <em>Azure Function<\/em> olu\u015fturulmas\u0131 ve GrayLog&#8217;a log g\u00f6nderilmesi<\/h4>\n<p><a href=\"\/wp-content\/uploads\/2019\/03\/azure_functions.jpeg\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-2582 lazyload\" data-src=\"\/wp-content\/uploads\/2019\/03\/azure_functions.jpeg\" alt=\"\" width=\"790\" height=\"480\" data-srcset=\"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2019\/03\/azure_functions.jpeg 790w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2019\/03\/azure_functions-300x182.jpeg 300w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2019\/03\/azure_functions-768x467.jpeg 768w\" data-sizes=\"(max-width: 790px) 100vw, 790px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 790px; --smush-placeholder-aspect-ratio: 790\/480;\" \/><\/a><\/p>\n<p><em>Event Hub<\/em> \u00fczerinde art\u0131k request ve response log&#8217;lar\u0131n\u0131 tutuyoruz. Bu log&#8217;lar\u0131 <em>Event Hub<\/em> \u00fczerinden consume edebilmek i\u00e7in farkl\u0131 y\u00f6ntemler mevcut. Ben ise bu noktada, herhangi ba\u015fka bir ekstra i\u015fle u\u011fra\u015fmamak i\u00e7in, <em>serverless<\/em> compute olan\u00a0<em>Azure Functions<\/em>&#8216;\u0131 tercih ettim.<\/p>\n<p>\u00d6ncelikle <em>Azure Function<\/em> olu\u015fturma i\u015flemini, <em><a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/azure-functions\/functions-create-first-function-vs-code\" target=\"_blank\" rel=\"noopener\">buradaki<\/a><\/em> dok\u00fcmantasyonu takip ederecek ger\u00e7ekle\u015ftirelim.<\/p>\n<p><a href=\"\/wp-content\/uploads\/2019\/03\/eventhubtrigger.jpg\"><img decoding=\"async\" class=\"aligncenter wp-image-2569 lazyload\" data-src=\"\/wp-content\/uploads\/2019\/03\/eventhubtrigger.jpg\" alt=\"\" width=\"611\" height=\"357\" data-srcset=\"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2019\/03\/eventhubtrigger.jpg 1204w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2019\/03\/eventhubtrigger-300x175.jpg 300w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2019\/03\/eventhubtrigger-768x449.jpg 768w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2019\/03\/eventhubtrigger-1024x599.jpg 1024w\" data-sizes=\"(max-width: 611px) 100vw, 611px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 611px; --smush-placeholder-aspect-ratio: 611\/357;\" \/><\/a><\/p>\n<p>Dok\u00fcmantasyon i\u00e7erisinde &#8220;<em>Create an HTTP triggered function<\/em>&#8221; k\u0131sm\u0131na geldi\u011finizde ise, &#8220;<em>Change template filter<\/em>&#8221; se\u00e7ene\u011fine t\u0131klayarak &#8220;<em>All<\/em>&#8221; opsiyonunu se\u00e7elim. Ard\u0131ndan yukar\u0131daki gibi\u00a0 &#8220;<em>EventHubTrigger<\/em>&#8221; opsiyonunu se\u00e7elim. Devam\u0131nda ise function&#8217;a bir isim verelim (ben <em>RequestLoggingFunction<\/em> ismini kulland\u0131m) ve ilgili ad\u0131mlar\u0131 takip ederek, function olu\u015fturma i\u015flemini tamamlayal\u0131m.<\/p>\n<p>Art\u0131k bir\u00a0<em>Azure Function<\/em> template&#8217;ine sahibiz.<\/p>\n<p>Burada yapaca\u011f\u0131m\u0131z iki adet i\u015flem var.<\/p>\n<ol>\n<li>Log&#8217;lar\u0131 <em>Event Hub<\/em> \u00fczerinden consume edece\u011fiz.<\/li>\n<li>Sonra log&#8217;lar\u0131\u00a0<em>GrayLog<\/em> i\u00e7erisine g\u00f6nderece\u011fiz (e\u011fer siz farkl\u0131 bir log sa\u011flay\u0131c\u0131s\u0131 kullan\u0131yorsan\u0131z, onu entegre edebilirsiniz)<\/li>\n<\/ol>\n<p>Biz hali haz\u0131rda <em>GrayLog<\/em> kulland\u0131\u011f\u0131m\u0131z i\u00e7in, request ve response message log&#8217;lar\u0131n\u0131 da\u00a0<em>GrayLog<\/em> i\u00e7erisinde tutmaya karar verdim. Dilerseniz\u00a0<em>Moesif<\/em> gibi farkl\u0131 \u00e7\u00f6z\u00fcmlere de bir g\u00f6z atabilirsiniz.<\/p>\n<blockquote><p><em>GrayLog<\/em> kurulumu hakk\u0131nda bilgi edinmek isterseniz, <em><a href=\"https:\/\/gokhan-gokalp.com\/en\/asp-net-core-serisi-02-nlog-ve-graylog-kullanarak-loglama-islemlerini-merkezilestirme\/\" target=\"_blank\" rel=\"noopener\">\u015fu<\/a><\/em> makaleme bir g\u00f6z atabilirsiniz.<\/p><\/blockquote>\n<p>\u00d6ncelikle <em>NLog<\/em>&#8216;un <em>Gelf<\/em> target paketini, <em>NuGet<\/em> \u00fczerinden projeye a\u015fa\u011f\u0131daki gibi ekleyelim.<\/p>\n<pre class=\"lang:default decode:true \">dotnet add package NLog.Web.AspNetCore.Targets.Gelf<\/pre>\n<p>Ard\u0131ndan &#8220;<em>Models<\/em>&#8221; isminde bir klas\u00f6r olu\u015fturarak, a\u015fa\u011f\u0131daki \u00fc\u00e7 class&#8217;\u0131 tan\u0131mlayal\u0131m.<\/p>\n<pre class=\"lang:c# decode:true\">public class HTTPRequestMessageLog\r\n{\r\n    public string Method { get; set; }\r\n    public Guid MessageId { get; set; }\r\n    public string UrlPath { get; set; }\r\n    public string Content { get; set; }\r\n}<\/pre>\n<pre class=\"lang:c# decode:true\">public class HTTPResponseMessageLog\r\n{\r\n    public Guid MessageId { get; set; }\r\n    public string StatusCode { get; set; }\r\n    public string Content { get; set; }\r\n}<\/pre>\n<blockquote><p><em><strong>NOT<\/strong><\/em>: Message log structure&#8217;\u0131n\u0131, kendinize g\u00f6re de\u011fi\u015ftirebilirsiniz.<\/p><\/blockquote>\n<pre class=\"lang:c# decode:true \">public class HttpMessage\r\n{\r\n    public Guid MessageId { get; set; }\r\n    public bool IsRequest { get; set; }\r\n    public HttpRequestMessage HttpRequestMessage { get; set; }\r\n    public HttpResponseMessage HttpResponseMessage { get; set; }\r\n\r\n\r\n    public static HttpMessage Parse(Stream stream)\r\n    {\r\n        using (var sr = new StreamReader(stream))\r\n        {\r\n            return Parse(sr.ReadToEnd());\r\n        }\r\n    }\r\n\r\n    public static HttpMessage Parse(string data)\r\n    {\r\n        var httpMessage = new HttpMessage();\r\n\r\n        HttpContent content;\r\n        using (var sr = new StringReader(data))\r\n        {\r\n            \/\/ First line of data is (request|response) followed by a GUID to link request to response\r\n            \/\/ Rest of data is in message\/http format\r\n\r\n            var firstLine = sr.ReadLine().Split(':');\r\n            if (firstLine.Length &lt; 2)\r\n            {\r\n                throw new ArgumentException(\"Invalid formatted event :\" + data);\r\n            }\r\n            httpMessage.IsRequest = firstLine[0] == \"request\";\r\n            httpMessage.MessageId = Guid.Parse(firstLine[1]);\r\n\r\n            var stream = new MemoryStream(Encoding.UTF8.GetBytes(sr.ReadToEnd()));\r\n            stream.Position = 0;\r\n            content = new StreamContent(stream);\r\n        }\r\n\r\n        var contentType = new MediaTypeHeaderValue(\"application\/http\");\r\n        content.Headers.ContentType = contentType;\r\n\r\n        if (httpMessage.IsRequest)\r\n        {\r\n            contentType.Parameters.Add(new NameValueHeaderValue(\"msgtype\", \"request\"));\r\n            \r\n            \/\/ Using .Result isn't too evil because content is a locally buffered memory stream\r\n            \/\/ Although if this were hosted in a System.Web based ASP.NET host it might block\r\n            httpMessage.HttpRequestMessage = content.ReadAsHttpRequestMessageAsync().Result;  \r\n        }\r\n        else\r\n        {\r\n            contentType.Parameters.Add(new NameValueHeaderValue(\"msgtype\", \"response\"));\r\n            httpMessage.HttpResponseMessage = content.ReadAsHttpResponseMessageAsync().Result;\r\n        }\r\n        return httpMessage;\r\n    }\r\n}<\/pre>\n<p><em>Event Hub<\/em> \u00fczerinden consume edece\u011fimiz log data&#8217;s\u0131n\u0131, &#8220;<em>HttpMessage<\/em>&#8221; class&#8217;\u0131 vas\u0131tas\u0131yla &#8220;<em>HttpRequestMessage<\/em>&#8221; ve &#8220;<em>HttpResponseMessage<\/em>&#8221; type&#8217;lar\u0131na parse edece\u011fiz.<\/p>\n<blockquote><p><em>https:\/\/github.com\/dgilling\/ApimEventProcessor\/blob\/master\/src\/ApimEventProcessor\/HttpMessage.cs<\/em><\/p><\/blockquote>\n<p>Function template&#8217;i ile gelen class&#8217;\u0131 ise a\u015fa\u011f\u0131daki gibi d\u00fczenleyelim.<\/p>\n<pre class=\"lang:c# decode:true\">public static class RequestLoggingFunction\r\n{\r\n    private static NLog.ILogger logger = null;\r\n\r\n    [FunctionName (\"RequestLoggingFunction\")]\r\n    public static async Task Run ([EventHubTrigger (\"my-log-hub\", Connection = \"EVENTHUB_CONNECTION\")] EventData[] events, ILogger log, ExecutionContext context)\r\n    {\r\n        ConfigureLogger (context.FunctionAppDirectory);\r\n\r\n        var exceptions = new List&lt;Exception&gt; ();\r\n\r\n        foreach (EventData eventData in events)\r\n        {\r\n            try\r\n            {\r\n                string messageBody = Encoding.UTF8.GetString (eventData.Body.Array, eventData.Body.Offset, eventData.Body.Count);\r\n                var httpMessage = HttpMessage.Parse (messageBody);\r\nhttpMessage.\r\n                if (httpMessage.IsRequest)\r\n                {\r\n                    var httpRequestMessageLog = new HTTPRequestMessageLog ();\r\n\r\n                    httpRequestMessageLog.MessageId = httpMessage.MessageId;\r\n                    httpRequestMessageLog.UrlPath = httpMessage.HttpRequestMessage.RequestUri.ToString ();\r\n                    httpRequestMessageLog.Method = httpMessage.HttpRequestMessage.Method.Method;\r\n                    httpRequestMessageLog.Content = await httpMessage.HttpRequestMessage.Content.ReadAsStringAsync ();\r\n\r\n                    logger.Info (JsonConvert.SerializeObject (httpRequestMessageLog));\r\n                }\r\n                else\r\n                {\r\n                    var httpResponseMessageLog = new HTTPResponseMessageLog ();\r\n\r\n                    httpResponseMessageLog.MessageId = httpMessage.MessageId;\r\n                    httpResponseMessageLog.StatusCode = httpMessage.HttpResponseMessage.StatusCode.ToString ();\r\n                    httpResponseMessageLog.Content = await httpMessage.HttpResponseMessage.Content.ReadAsStringAsync ();\r\n\r\n                    logger.Info (JsonConvert.SerializeObject (httpResponseMessageLog));\r\n                }\r\n\r\n                await Task.Yield ();\r\n            }\r\n            catch (Exception e)\r\n            {\r\n                \/\/ We need to keep processing the rest of the batch - capture this exception and continue.\r\n                \/\/ Also, consider capturing details of the message that failed processing so it can be processed again later.\r\n                exceptions.Add (e);\r\n            }\r\n        }\r\n\r\n        \/\/ Once processing of the batch is complete, if any messages in the batch failed processing throw an exception so that there is a record of the failure.\r\n\r\n        if (exceptions.Count &gt; 1)\r\n            throw new AggregateException (exceptions);\r\n\r\n        if (exceptions.Count == 1)\r\n            throw exceptions.Single ();\r\n    }\r\n\r\n    private static void ConfigureLogger (string appDirectory)\r\n    {\r\n        if (logger == null)\r\n        {\r\n            string nlogConfigPath = Path.Combine (appDirectory, \"nlog.config\");\r\n            NLog.LogManager.Configuration = new XmlLoggingConfiguration (nlogConfigPath);\r\n            logger = NLog.LogManager.GetCurrentClassLogger ();\r\n        }\r\n    }\r\n}<\/pre>\n<blockquote><p><em><strong>NOT<\/strong><\/em>: &#8220;<em>EventHubTrigger<\/em>&#8221; attribute&#8217;\u00fcne parametre olarak set etti\u011fim &#8220;<em>my-log-hub<\/em>&#8221; ve &#8220;<em>EVENTHUB_CONNECTION<\/em>&#8221; key&#8217;lerini d\u00fczenlemeyi unutmay\u0131n.<\/p><\/blockquote>\n<p>Function i\u00e7erisinde k\u0131saca neler yapt\u0131\u011f\u0131m\u0131za bir bakal\u0131m.<\/p>\n<p><em>GrayLog<\/em>&#8216;a\u00a0log g\u00f6nderebilmek i\u00e7in <em>NLog<\/em>&#8216;un logger&#8217;\u0131n\u0131 configure ettik. &#8220;<em>Run<\/em>&#8221; method&#8217;u i\u00e7erisinde ise event&#8217;in\u00a0parse edilmesinin ard\u0131ndan ilgili event type&#8217;\u0131na g\u00f6re, log&#8217;lama i\u015flemini ger\u00e7ekle\u015ftirdik.<\/p>\n<p>\u015eimdi ise function&#8217;\u0131n root dizini alt\u0131nda, &#8220;<em>nlog.config<\/em>&#8221; file&#8217;\u0131n\u0131 a\u015fa\u011f\u0131daki gibi olu\u015fturmam\u0131z gerekmektedir.<\/p>\n<pre class=\"lang:default decode:true\">&lt;?xml version=\"1.0\" encoding=\"utf-8\" ?&gt;\r\n&lt;nlog xmlns=\"http:\/\/www.nlog-project.org\/schemas\/NLog.xsd\"\r\n      xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\"\r\n      autoReload=\"true\"\r\n      throwExceptions=\"false\"\r\n      internalLogLevel=\"Off\"&gt;\r\n  &lt;extensions&gt;\r\n    &lt;add assembly=\"NLog.Web.AspNetCore\"\/&gt;\r\n    &lt;add assembly=\"NLog.Web.AspNetCore.Targets.Gelf\"\/&gt;\r\n  &lt;\/extensions&gt;\r\n  &lt;targets&gt;\r\n    &lt;target xsi:type=\"Gelf\" name=\"graylog\" endpoint=\"udp:\/\/localhost:12201\" facility=\"APM.RequestLogging.Function\" SendLastFormatParameter=\"true\" \/&gt;\r\n  &lt;\/targets&gt;\r\n  &lt;rules&gt;\r\n    &lt;logger level=\"Info\" writeTo=\"graylog\" \/&gt;\r\n  &lt;\/rules&gt;\r\n&lt;\/nlog&gt;<\/pre>\n<blockquote><p><em><strong>NOT<\/strong><\/em>: <em>GrayLog<\/em> &#8220;<em>endpoint<\/em>&#8221; ini de d\u00fczenlemeyi unutmay\u0131n.<\/p><\/blockquote>\n<h4>5.\u00a0Olu\u015fturulan <em>Azure Function<\/em>&#8216;\u0131n deploy edilmesi<\/h4>\n<p>Art\u0131k olu\u015fturdu\u011fumuz function&#8217;\u0131 deploy etmeye haz\u0131r\u0131z. Deployment i\u015flemini h\u0131zl\u0131ca ger\u00e7ekle\u015ftirebilmek i\u00e7in, ilk olarak <em><a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/azure-functions\/functions-create-first-function-vs-code#publish-the-project-to-azure\" target=\"_blank\" rel=\"noopener\">buradaki<\/a><\/em> ad\u0131mlar\u0131 takip edelim.<\/p>\n<blockquote><p><em><strong>NOT<\/strong><\/em>: Azure \u00fczerinde function olu\u015ftururken, <strong>pricing tier<\/strong>&#8216;\u0131n\u0131 dikkatli se\u00e7menizi \u00f6neririm. Ben t\u00fcm request ve response message&#8217;lar\u0131n\u0131 log&#8217;layacak function&#8217;\u0131m\u0131 kotrol alt\u0131nda tutabilmek i\u00e7in &#8220;<em>consumption<\/em>&#8221; plan yerine, &#8220;<em>app service<\/em>&#8221; plan&#8217;\u0131 tercih ettim.<\/p><\/blockquote>\n<p>Deployment i\u015flemini tamamlad\u0131ktan sonra,\u00a0<em>Event Hub<\/em>&#8216;\u0131n connection string bilgisini\u00a0<em>Azure Portal<\/em> \u00fczerinden function&#8217;\u0131n app settings b\u00f6l\u00fcm\u00fcne eklememiz gerekmektedir.<\/p>\n<p>\u00d6ncelikle portal \u00fczerinden &#8220;<em>Function Apps<\/em>&#8221; sekmesine girelim ve olu\u015fturmu\u015f oldu\u011fumuz function&#8217;a t\u0131klayal\u0131m. Ard\u0131ndan &#8220;<em>Platform features<\/em>&#8221; sekmesine ge\u00e7erek &#8220;<em>Application settings<\/em>&#8221; se\u00e7ene\u011fine t\u0131klayal\u0131m.<\/p>\n<p><a href=\"\/wp-content\/uploads\/2019\/03\/function_app_set.jpg\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-2579 lazyload\" data-src=\"\/wp-content\/uploads\/2019\/03\/function_app_set.jpg\" alt=\"\" width=\"1960\" height=\"556\" data-srcset=\"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2019\/03\/function_app_set.jpg 1960w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2019\/03\/function_app_set-300x85.jpg 300w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2019\/03\/function_app_set-768x218.jpg 768w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2019\/03\/function_app_set-1024x290.jpg 1024w\" data-sizes=\"(max-width: 1960px) 100vw, 1960px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 1960px; --smush-placeholder-aspect-ratio: 1960\/556;\" \/><\/a><\/p>\n<p>Ben function i\u00e7erisindeki &#8220;<em>Connection<\/em>&#8221; key&#8217;ini &#8220;<em>EVENTHUB_CONNECTION<\/em>&#8221; ad\u0131yla tan\u0131mlad\u0131\u011f\u0131m i\u00e7in, app settings i\u00e7erisine de ayn\u0131 \u015fekilde ekledim.<\/p>\n<p>Art\u0131k haz\u0131r\u0131z. E\u011fer herhangi bir hata yapmad\u0131ysak, olu\u015fturdu\u011fumuz function ba\u015far\u0131yla \u00e7al\u0131\u015fmaya ba\u015flayacakt\u0131r. Function&#8217;\u0131n sorunsuz \u00e7al\u0131\u015ft\u0131\u011f\u0131n\u0131 anlayabilmek i\u00e7in ise, yukar\u0131daki ekranda bulunan &#8220;<em>Monitor<\/em>&#8221; sekmesine girerek kontrol edebilirsiniz.<\/p>\n<p>\u00d6rnek bir request log&#8217;u ise\u00a0<em>GrayLog <\/em>i\u00e7erisinden a\u015fa\u011f\u0131daki gibi g\u00f6r\u00fcnecektir.<br \/>\n<a href=\"\/wp-content\/uploads\/2019\/03\/log_result_graylog.jpg\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-2580 lazyload\" data-src=\"\/wp-content\/uploads\/2019\/03\/log_result_graylog.jpg\" alt=\"\" width=\"2426\" height=\"672\" data-srcset=\"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2019\/03\/log_result_graylog.jpg 2426w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2019\/03\/log_result_graylog-300x83.jpg 300w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2019\/03\/log_result_graylog-768x213.jpg 768w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2019\/03\/log_result_graylog-1024x284.jpg 1024w\" data-sizes=\"(max-width: 2426px) 100vw, 2426px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 2426px; --smush-placeholder-aspect-ratio: 2426\/672;\" \/><\/a><\/p>\n<h2>Sonu\u00e7<\/h2>\n<p>Her ne kadar basit bir i\u015flem gibi g\u00f6r\u00fcnse de, request ve response message&#8217;lar\u0131n\u0131n log&#8217;lanmas\u0131 bir \u00e7ok durum i\u00e7in \u00f6nem arz etmektedir. Ayr\u0131ca bu i\u015flemi \u00e7ok fazla bir overhead yaratmadan ve\u00a0<em>Azure<\/em>&#8216;un bize sa\u011flam\u0131\u015f oldu\u011fu service&#8217;leri kullanarak, mevcut sistemimiz i\u00e7erisinden nas\u0131l ger\u00e7ekle\u015ftirdi\u011fimi g\u00f6stermeye \u00e7al\u0131\u015ft\u0131m.<\/p>\n<p>Happy clouding!<\/p>\n<h4>Referanslar<\/h4>\n<blockquote><p>https:\/\/docs.microsoft.com\/en-us\/azure\/api-management\/api-management-howto-log-event-hubs<br \/>\nhttps:\/\/docs.microsoft.com\/en-us\/azure\/api-management\/api-management-log-to-eventhub-sample<br \/>\nhttps:\/\/docs.microsoft.com\/en-us\/azure\/azure-functions\/functions-create-first-function-vs-code<\/p><\/blockquote>\n","protected":false},"excerpt":{"rendered":"<p>Sizlerinde bildi\u011fi gibi hemen hemen her backend application&#8217;\u0131n\u0131n sahip olmas\u0131 gereken en temel \u00f6zelliklerden birisi, request ve response&#8216;lar\u0131n log&#8216;lanmas\u0131d\u0131r. \u00d6zellikle \u00e7oklu\u00a0API kullan\u0131m\u0131n\u0131n s\u00f6z konusu oldu\u011fu ortamlarda, &#8220;nice-to-have&#8221; durumundan &#8220;must-have&#8221; durumuna ge\u00e7i\u015f yapan temel bir \u00f6zellik. \u00c7\u00fcnk\u00fc \u00f6yle bir zaman geliyor ki, API&#8216;\u0131\u00a0call eden bir client&#8217;a,&#8230;<\/p>\n<div class=\"more-link-wrapper\"><a class=\"more-link\" href=\"https:\/\/gokhan-gokalp.com\/tr\/logging-api-requests-and-responses-to-graylog-over-azure-api-management-using-azure-functions\/\">Devam\u0131n\u0131 okuyun<span class=\"screen-reader-text\">API Request ve Response&#8217;lar\u0131n\u0131 Azure API Management \u00fczerinden Azure Funtions Kullanarak GrayLog&#8217;a Loglama<\/span><\/a><\/div>\n","protected":false},"author":1,"featured_media":2553,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[505,417,418,433],"tags":[419,426,444,516,517,515,425,440,305,487],"class_list":["post-2547","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-net-core","category-asp-net-core","category-azure","category-logging","tag-asp-net-core","tag-asp-net-core-graylog","tag-asp-net-core-kubernetes","tag-azure-api-management","tag-azure-event-hub","tag-azure-functions","tag-graylog","tag-kubernetes","tag-nlog","tag-serverless","entry"],"translation":{"provider":"WPGlobus","version":"3.0.2","language":"tr","enabled_languages":["en","tr"],"languages":{"en":{"title":true,"content":true,"excerpt":false},"tr":{"title":true,"content":true,"excerpt":false}}},"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.3 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>API Request ve Response&#039;lar\u0131n\u0131 Azure API Management \u00fczerinden Azure Funtions Kullanarak GrayLog&#039;a Loglama - G\u00f6khan G\u00f6kalp<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/gokhan-gokalp.com\/logging-api-requests-and-responses-to-graylog-over-azure-api-management-using-azure-functions\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"API Request ve Response&#039;lar\u0131n\u0131 Azure API Management \u00fczerinden Azure Funtions Kullanarak GrayLog&#039;a Loglama - G\u00f6khan G\u00f6kalp\" \/>\n<meta property=\"og:url\" content=\"https:\/\/gokhan-gokalp.com\/logging-api-requests-and-responses-to-graylog-over-azure-api-management-using-azure-functions\/\" \/>\n<meta property=\"og:site_name\" content=\"G\u00f6khan G\u00f6kalp\" \/>\n<meta property=\"article:published_time\" content=\"2019-03-23T07:37:06+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2019-03-23T07:42:59+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2019\/03\/graylog-azure-functions-api-management.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1280\" \/>\n\t<meta property=\"og:image:height\" content=\"853\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"G\u00f6khan G\u00f6kalp\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Yazan:\" \/>\n\t<meta name=\"twitter:data1\" content=\"G\u00f6khan G\u00f6kalp\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tahmini okuma s\u00fcresi\" \/>\n\t<meta name=\"twitter:data2\" content=\"25 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/logging-api-requests-and-responses-to-graylog-over-azure-api-management-using-azure-functions\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/logging-api-requests-and-responses-to-graylog-over-azure-api-management-using-azure-functions\\\/\"},\"author\":{\"name\":\"G\u00f6khan G\u00f6kalp\",\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/#\\\/schema\\\/person\\\/7e2a7fa98babd22a5fdae563c4b8cdbe\"},\"headline\":\"API Request ve Response&#8217;lar\u0131n\u0131 Azure API Management \u00fczerinden Azure Funtions Kullanarak GrayLog&#8217;a Loglama\",\"datePublished\":\"2019-03-23T07:37:06+00:00\",\"dateModified\":\"2019-03-23T07:42:59+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/logging-api-requests-and-responses-to-graylog-over-azure-api-management-using-azure-functions\\\/\"},\"wordCount\":3575,\"commentCount\":1,\"publisher\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/#\\\/schema\\\/person\\\/7e2a7fa98babd22a5fdae563c4b8cdbe\"},\"image\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/logging-api-requests-and-responses-to-graylog-over-azure-api-management-using-azure-functions\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/uploads\\\/2019\\\/03\\\/graylog-azure-functions-api-management.jpg\",\"keywords\":[\"asp.net core\",\"asp.net core graylog\",\"asp.net core kubernetes\",\"azure api management\",\"azure event hub\",\"azure functions\",\"graylog\",\"kubernetes\",\"NLog\",\"serverless\"],\"articleSection\":[\".NET Core\",\"ASP.NET Core\",\"Azure\",\"Logging\"],\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/gokhan-gokalp.com\\\/logging-api-requests-and-responses-to-graylog-over-azure-api-management-using-azure-functions\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/logging-api-requests-and-responses-to-graylog-over-azure-api-management-using-azure-functions\\\/\",\"url\":\"https:\\\/\\\/gokhan-gokalp.com\\\/logging-api-requests-and-responses-to-graylog-over-azure-api-management-using-azure-functions\\\/\",\"name\":\"API Request ve Response'lar\u0131n\u0131 Azure API Management \u00fczerinden Azure Funtions Kullanarak GrayLog'a Loglama - G\u00f6khan G\u00f6kalp\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/logging-api-requests-and-responses-to-graylog-over-azure-api-management-using-azure-functions\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/logging-api-requests-and-responses-to-graylog-over-azure-api-management-using-azure-functions\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/uploads\\\/2019\\\/03\\\/graylog-azure-functions-api-management.jpg\",\"datePublished\":\"2019-03-23T07:37:06+00:00\",\"dateModified\":\"2019-03-23T07:42:59+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/logging-api-requests-and-responses-to-graylog-over-azure-api-management-using-azure-functions\\\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/gokhan-gokalp.com\\\/logging-api-requests-and-responses-to-graylog-over-azure-api-management-using-azure-functions\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/logging-api-requests-and-responses-to-graylog-over-azure-api-management-using-azure-functions\\\/#primaryimage\",\"url\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/uploads\\\/2019\\\/03\\\/graylog-azure-functions-api-management.jpg\",\"contentUrl\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/uploads\\\/2019\\\/03\\\/graylog-azure-functions-api-management.jpg\",\"width\":1280,\"height\":853},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/logging-api-requests-and-responses-to-graylog-over-azure-api-management-using-azure-functions\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/gokhan-gokalp.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Logging API Requests and Responses to GrayLog over Azure API Management using Azure Functions\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/#website\",\"url\":\"https:\\\/\\\/gokhan-gokalp.com\\\/\",\"name\":\"G\u00f6khan G\u00f6kalp\",\"description\":\"C# &amp; Python lover\",\"publisher\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/#\\\/schema\\\/person\\\/7e2a7fa98babd22a5fdae563c4b8cdbe\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/gokhan-gokalp.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"tr\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/#\\\/schema\\\/person\\\/7e2a7fa98babd22a5fdae563c4b8cdbe\",\"name\":\"G\u00f6khan G\u00f6kalp\",\"pronouns\":\"he\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/litespeed\\\/avatar\\\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1776170659\",\"url\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/litespeed\\\/avatar\\\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1776170659\",\"contentUrl\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/litespeed\\\/avatar\\\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1776170659\",\"caption\":\"G\u00f6khan G\u00f6kalp\"},\"logo\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/litespeed\\\/avatar\\\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1776170659\"},\"sameAs\":[\"https:\\\/\\\/gokhan-gokalp.com\"],\"url\":\"https:\\\/\\\/gokhan-gokalp.com\\\/tr\\\/author\\\/gok-gokalp\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"API Request ve Response'lar\u0131n\u0131 Azure API Management \u00fczerinden Azure Funtions Kullanarak GrayLog'a Loglama - G\u00f6khan G\u00f6kalp","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/gokhan-gokalp.com\/logging-api-requests-and-responses-to-graylog-over-azure-api-management-using-azure-functions\/","og_locale":"tr_TR","og_type":"article","og_title":"API Request ve Response'lar\u0131n\u0131 Azure API Management \u00fczerinden Azure Funtions Kullanarak GrayLog'a Loglama - G\u00f6khan G\u00f6kalp","og_url":"https:\/\/gokhan-gokalp.com\/logging-api-requests-and-responses-to-graylog-over-azure-api-management-using-azure-functions\/","og_site_name":"G\u00f6khan G\u00f6kalp","article_published_time":"2019-03-23T07:37:06+00:00","article_modified_time":"2019-03-23T07:42:59+00:00","og_image":[{"width":1280,"height":853,"url":"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2019\/03\/graylog-azure-functions-api-management.jpg","type":"image\/jpeg"}],"author":"G\u00f6khan G\u00f6kalp","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"G\u00f6khan G\u00f6kalp","Tahmini okuma s\u00fcresi":"25 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/gokhan-gokalp.com\/logging-api-requests-and-responses-to-graylog-over-azure-api-management-using-azure-functions\/#article","isPartOf":{"@id":"https:\/\/gokhan-gokalp.com\/logging-api-requests-and-responses-to-graylog-over-azure-api-management-using-azure-functions\/"},"author":{"name":"G\u00f6khan G\u00f6kalp","@id":"https:\/\/gokhan-gokalp.com\/#\/schema\/person\/7e2a7fa98babd22a5fdae563c4b8cdbe"},"headline":"API Request ve Response&#8217;lar\u0131n\u0131 Azure API Management \u00fczerinden Azure Funtions Kullanarak GrayLog&#8217;a Loglama","datePublished":"2019-03-23T07:37:06+00:00","dateModified":"2019-03-23T07:42:59+00:00","mainEntityOfPage":{"@id":"https:\/\/gokhan-gokalp.com\/logging-api-requests-and-responses-to-graylog-over-azure-api-management-using-azure-functions\/"},"wordCount":3575,"commentCount":1,"publisher":{"@id":"https:\/\/gokhan-gokalp.com\/#\/schema\/person\/7e2a7fa98babd22a5fdae563c4b8cdbe"},"image":{"@id":"https:\/\/gokhan-gokalp.com\/logging-api-requests-and-responses-to-graylog-over-azure-api-management-using-azure-functions\/#primaryimage"},"thumbnailUrl":"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2019\/03\/graylog-azure-functions-api-management.jpg","keywords":["asp.net core","asp.net core graylog","asp.net core kubernetes","azure api management","azure event hub","azure functions","graylog","kubernetes","NLog","serverless"],"articleSection":[".NET Core","ASP.NET Core","Azure","Logging"],"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/gokhan-gokalp.com\/logging-api-requests-and-responses-to-graylog-over-azure-api-management-using-azure-functions\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/gokhan-gokalp.com\/logging-api-requests-and-responses-to-graylog-over-azure-api-management-using-azure-functions\/","url":"https:\/\/gokhan-gokalp.com\/logging-api-requests-and-responses-to-graylog-over-azure-api-management-using-azure-functions\/","name":"API Request ve Response'lar\u0131n\u0131 Azure API Management \u00fczerinden Azure Funtions Kullanarak GrayLog'a Loglama - G\u00f6khan G\u00f6kalp","isPartOf":{"@id":"https:\/\/gokhan-gokalp.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/gokhan-gokalp.com\/logging-api-requests-and-responses-to-graylog-over-azure-api-management-using-azure-functions\/#primaryimage"},"image":{"@id":"https:\/\/gokhan-gokalp.com\/logging-api-requests-and-responses-to-graylog-over-azure-api-management-using-azure-functions\/#primaryimage"},"thumbnailUrl":"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2019\/03\/graylog-azure-functions-api-management.jpg","datePublished":"2019-03-23T07:37:06+00:00","dateModified":"2019-03-23T07:42:59+00:00","breadcrumb":{"@id":"https:\/\/gokhan-gokalp.com\/logging-api-requests-and-responses-to-graylog-over-azure-api-management-using-azure-functions\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/gokhan-gokalp.com\/logging-api-requests-and-responses-to-graylog-over-azure-api-management-using-azure-functions\/"]}]},{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/gokhan-gokalp.com\/logging-api-requests-and-responses-to-graylog-over-azure-api-management-using-azure-functions\/#primaryimage","url":"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2019\/03\/graylog-azure-functions-api-management.jpg","contentUrl":"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2019\/03\/graylog-azure-functions-api-management.jpg","width":1280,"height":853},{"@type":"BreadcrumbList","@id":"https:\/\/gokhan-gokalp.com\/logging-api-requests-and-responses-to-graylog-over-azure-api-management-using-azure-functions\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/gokhan-gokalp.com\/"},{"@type":"ListItem","position":2,"name":"Logging API Requests and Responses to GrayLog over Azure API Management using Azure Functions"}]},{"@type":"WebSite","@id":"https:\/\/gokhan-gokalp.com\/#website","url":"https:\/\/gokhan-gokalp.com\/","name":"G\u00f6khan G\u00f6kalp","description":"C# &amp; Python lover","publisher":{"@id":"https:\/\/gokhan-gokalp.com\/#\/schema\/person\/7e2a7fa98babd22a5fdae563c4b8cdbe"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/gokhan-gokalp.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"tr"},{"@type":["Person","Organization"],"@id":"https:\/\/gokhan-gokalp.com\/#\/schema\/person\/7e2a7fa98babd22a5fdae563c4b8cdbe","name":"G\u00f6khan G\u00f6kalp","pronouns":"he","image":{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/gokhan-gokalp.com\/wp-content\/litespeed\/avatar\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1776170659","url":"https:\/\/gokhan-gokalp.com\/wp-content\/litespeed\/avatar\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1776170659","contentUrl":"https:\/\/gokhan-gokalp.com\/wp-content\/litespeed\/avatar\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1776170659","caption":"G\u00f6khan G\u00f6kalp"},"logo":{"@id":"https:\/\/gokhan-gokalp.com\/wp-content\/litespeed\/avatar\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1776170659"},"sameAs":["https:\/\/gokhan-gokalp.com"],"url":"https:\/\/gokhan-gokalp.com\/tr\/author\/gok-gokalp\/"}]}},"_links":{"self":[{"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/posts\/2547","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/comments?post=2547"}],"version-history":[{"count":31,"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/posts\/2547\/revisions"}],"predecessor-version":[{"id":2593,"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/posts\/2547\/revisions\/2593"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/media\/2553"}],"wp:attachment":[{"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/media?parent=2547"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/categories?post=2547"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/tags?post=2547"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}