https://buraksenyurt.com/Burak Selim Şenyurt - python2021-05-18T20:33:08+00:00Matematik Mühendisi Bir Bilgisayar Programcısının NotlarıBurak Selim SenyurtBlogEngine.Net Syndication Generatorhttps://buraksenyurt.com/opml.axdBurak Selim SenyurtMatematik Mühendisi Bir Bilgisayar Programcısının Notlarıtr-TRBurak Selim Şenyurt0.0000000.000000https://buraksenyurt.com/post/beeware-ile-linux-platformunda-desktop-uygulamasi-gelistirmek-ve-android-surumunu-olusturmakBeeWare ile Linux Platformunda Desktop Uygulaması Geliştirmek ve Android Sürümünü Oluşturmak2020-09-13T21:05:00+00:00bsenyurt<p><img src="https://buraksenyurt.com/image.axd?picture=/2020/skynet/29/beeware.png" alt="" align="right" />Geçenlerde Python ile ilgili bir şeyler ararken BeeWare isimli çalışmaya rastladım. Her yerde python ile native uygulama geliştirmek gibi bir felsefesi vardı. Eee zaten python her platformda yüklenip kullanılmıyor mu? Yoo tam olarak olay öyle değil aslında. BeeWare ürünü macOS, Linux ve Windows platformlarında native uygulama geliştirmek haricinde iOS ve Android için de destek sunan bir araçlar ve kütüphaneler topluluğu. Söz gelimi iOS ve macOS platformundaki Objective C kütüphaneleri ile Python arasında köprü görevi gören Rubicon ObjC isimli bir araç sunuyor. Java kütüphaneleri ile bir iletişim mi gerekiyor!? O zaman Rubicon Java var. Diğer yandan cross-platform için Toga isimli bir widget kütüphanesi kullanıyor. Ayrıca python projelerini tek başına çalışabilir uygulamalar haline getirmek için<em>(standalone native application)</em> Briefcase isimli başka bir araca sahip ki bir çoğunu birazdan kullanacağız.</p>
<p>Aslında olayı şöyle düşünebiliriz; Bu çatı sayesinde Android için Gradle çıktısı, iOS için XCode proje çıktısı, Linux için AppImage, Windows için MSI Installer ve macOS için doğrudan çalışabilir uygulama çıktıları üretebiliyoruz. Bana Xamarin ve Electron'u düşündürmedi değil<em>(Bu arada BeeWare'in Logo'su epey sevimli)</em></p>
<p>İddialı bir platform olduğunu ifade edebilirim. Elbette Skynet çalışmasını yaptığım ve derlemeyi hazırladığım tarih itibariyle ürünle ilgili değişiklikler olmuştur. O nedenle <a href="https://beeware.org/" target="_blank">şu adresten takip etmenizi</a> öneririm. Benim amacım her zaman olduğu gibi bunu Heimdal<em>(Ubuntu-20.04)</em> üzerinde denemek ve Linux'te çalışan bir masaüstü uygulaması geliştirmek. Hatta arkasına birde Android sürümünü eklemek. İşe uzun bir terminal çalışması ile başlıyoruz.</p>
<pre class="brush:bash;auto-links:false;toolbar:false" contenteditable="false"># Sistemde Python yüklü olsa bile ekstra bazı kütüphaneler de gerekiyor
# Lakin bu paketleri hangi amaçla yüklüyoruz, araştırmam lazım. Mazallah güvenlik açığı filan da olabilir. Aman dikkat!
sudo apt-get install libgirepository1.0-dev libcairo2-dev libpango1.0-dev libwebkit2gtk-4.0.37 gir1.2-webkit2-4.0
# Şimdi Python paketinin dağıtımında devreye girecek Briefcase aracını yükleyelim
# Bu arada 20.04 üstünde cookiecutter versiyonunu beğenmedi Heimdall. O nedenle cookiecuttor'ı da pip üstünden install ettim
python3 -m pip install briefcase
# Adettendir kurulan versiyonu bir kontrol etmek iyi olabilir
briefcase --version
# Şimdi yeni projenin açılışını yapabiliriz
briefcase new
# Sorulan sorulara verdiğim cevaplar doğrultusunda cardgame isimli bir proje oluştu.
# Carg Game isimli projenin GUI framework olarak Toga'yı seçtim.
# Buna göre projenin Linux, macOS, Windows dağıtımlarındaki gereksinimleri ile birlikte
# diğer sorduğu sorulara() verdiğim cevaplar pyproject.toml (toml = Tom's Obvious Minimal Language) içerisine yazıldı.
# Bu dosyayı incelemekte yarar var.</pre>
<p><img src="https://buraksenyurt.com/image.axd?picture=/2020/skynet/29/Screenshot_01.png" alt="" /></p>
<p>Bir yerlere kod yazmayacak mıyız dediğinizi duyar gibiyim? Sonuçta bir arayüz tasarlamak gerekiyor öyle değil mi? Bunu src/cardgame altındaki app.py dosyasında yapabiliriz. Aynen aşağıdaki kod parçasında olduğu gibi.</p>
<pre class="brush:py;auto-links:false;toolbar:false" contenteditable="false">"""
A simple desktop application on Ubuntu
"""
import toga
from toga.style import Pack
from toga.style.pack import COLUMN, ROW
class CardGame(toga.App):
def startup(self):
# Bu ana form gibi bir şey. Toga uygulamalarında kutu koleksiyonları da söz konusu olabilir(Box Collection)
# direction için verdiğim Column ile main_box'a eklenecek kontrollerin sütun formatında aşağıya doğru ineceğini söyledik
main_box = toga.Box(style=Pack(direction=COLUMN))
# Şimdi birkaç kontrol ekleyelim
# Birkaç Label ekliyoruz ve onlara padding stilleri veriyoruz
lblNickname = toga.Label(
'Takma adını söyler misin?', style=Pack(padding=(0, 10))) # Biraz padding ayarı yaptık
lblColor = toga.Label('En sevdiğin renk?', style=Pack(padding=(0, 10)))
lblLuckyNumber = toga.Label(
'Şans numaran peki?', style=Pack(padding=(0, 10)))
self.lblMyGuess = toga.Label('...', style=Pack(flex=1, padding=10))
# Şimdi yukarıdaki sorular için birer Input kontrolü ekleyelim
# Bunları sınıfın Instance Variable'ları olarak tanımlıyoruz ki erişmemiz kolay olsun.
self.txtNickname = toga.TextInput(style=Pack(padding=5, flex=1))
self.txtColor = toga.TextInput()
self.txtLuckyNumber = toga.TextInput()
# Şimdi yukarıdaki kontrolleri bir kutuya koyalım. (Box)
boxIdentity = toga.Box(style=Pack(direction=COLUMN))
boxIdentity.add(lblNickname)
boxIdentity.add(self.txtNickname)
boxIdentity.add(lblColor)
boxIdentity.add(self.txtColor)
boxIdentity.add(lblLuckyNumber)
boxIdentity.add(self.txtLuckyNumber)
# Sonra bu kontrolleri içeren kutuyu ana kutuya ekleyelim
main_box.add(boxIdentity)
# Bir tane de Button oluşturup ana kutuya ilave edelim
# Button'a basıldığında da bntGuess_OnPress isimli olay metodu çalışacak
btnGuess = toga.Button(
'Tahmin Yap', on_press=self.btnGuess_OnPress, style=Pack(width=100, padding=10))
main_box.add(btnGuess)
main_box.add(self.lblMyGuess)
# Title ile biraz oynadım. Keh keh keh :P
self.main_window = toga.MainWindow(
title=self.formal_name+" Version 1.0")
self.main_window.content = main_box
self.main_window.show()
# Windows Forms tarafına ne kadar da benziyor
def btnGuess_OnPress(self, widget):
print('Belki loglama amaçlı kullanılabilir')
# Burada validasyon yapmak gerekir mi? Yoksa kontrollerin validasyon için nitelikleri var mıdır?
summary = "Merhaba {nick}. Favori rengin {color} ve şans numaran {number}".format(
nick=self.txtNickname.value, color=self.txtColor.value, number=self.txtLuckyNumber.value)
self.lblMyGuess.text = summary
'''
Uygulama yüklendiğinde main metodu CardGame sınıfını örnekler
Bunu bir Windows Forms sınıfının yüklenmesi olarak düşünüyorum ;)
'''
def main():
return CardGame()</pre>
<p>Aslında Windows Forms veya Asp.Net Web Forms ile kodlama yaptıysanız buradaki kontrollerin yerleşimleri ile event'leri anlamanız son derece kolay. Gelelim çalışma zamanına. Linux, MacOS, Windows...Hiç farketmez. Hepsinde briefcase aracını kullanarak uygulamayı işletebiliriz.</p>
<pre class="brush:bash;auto-links:false;toolbar:false" contenteditable="false">briefcase dev</pre>
<p>İlk çalışma sırasında üzerinde olduğumuz platforma göre gerekli bazı bağımlılıklar indirilir<em>(Toga paketleri gibi)</em></p>
<p><img src="https://buraksenyurt.com/image.axd?picture=/2020/skynet/29/Screenshot_02.png" alt="" /></p>
<p>Ve ardından uygulama aşağıdaki ekran görüntüsünde olduğu gibi ayağa kalkar.</p>
<p><img src="https://buraksenyurt.com/image.axd?picture=/2020/skynet/29/Screenshot_03.png" alt="" /></p>
<h2>Dağıtım<em>(Deployment)</em></h2>
<p>Uygulama şu ana kadar development modda çalıştırıldı. Ancak onu paket haline getirip farklı platformlara da dağıtabiliriz. Ben normalde Linux için bir dağıtım paketi oluşturmayı düşünüyordum ancak uygulamayı Android için paketleyebilir miyiz diye de merak ettim. İşte uygulamanın android sürümüne dönüştürülmesi için yapmamız gerekenler.</p>
<pre class="brush:bash;auto-links:false;toolbar:false" contenteditable="false"># Uygulama klasöründeyken create ile bir android app oluşturulur(dakikalarca sürebiliyor)
briefcase create android
# ve build komutu ile de apk dosyası üretilir. Card Game/app/build/outputs/apk/debug/app-debug.apk altında oluşur (Gerekli SDK, NDK paketlerini indirdiği için ilk seferinde dakikalarca sürebiliyor)
briefcase build android
# Kontrol amaçlı olarak build edilen sürüm aşağıdaki gibi çalıştırılabilir.
# Burada sanal bir emülator'den yararlanılabileceği gibi gerçek bir Android cihazda kullanılabilir.
# Ben Create a new Android Emulator seçeneğini tercih ettim.
briefcase run android</pre>
<p>Ve bende tebessüm bırakan ekran görüntüsü :-)</p>
<p><img src="https://buraksenyurt.com/image.axd?picture=/2020/skynet/29/Screenshot_04.png" alt="" /></p>
<p>Bu örnek için andorid klasörü tüm bağımlılıkları ile birlikte 500 megabyte'tan fazla yer tuttu. APK dosyası ise yaklaşık 50 Mb civarındaydı. Böylesine basit bir kobay uygulama için oldukça fazla yer harcandığını ifade edebilirim. Zaten genel olarak bu tip cross-platform çözümlerinin<em>(Xamarin, Electron vb)</em> özellikle mobil taraftaki en büyük sorunu da sanırım bu optimizasyo konusundaki sıkıntıları.</p>
<p>Peki örnekle ilgili daha neler yapabilirsiniz? Söz gelimi verileri SQLite gibi bir fiziki bir depolama alanında saklamayı deneyebilirsiniz<em>(Uzak bir REST servis üstünden de olabilir tabi)</em> Ayrıca elinizin altında bir macOS varsa iOS sürümü için bir dağıtım paketi üretip o platformda kullanmayı da düşünebilirsiniz. Uygulamamızın örnek kodlarına SkyNet <a href="https://github.com/buraksenyurt/skynet/tree/master/No%2029%20-%20What%20is%20BeeWare" target="_blank">github reposu üzerinden</a> erişebilirsiniz. Tekrardan görüşünceye dek hepinize iyi günler dilerim.</p>2020-09-13T21:05:00+00:00pyhtoncross platform developmentwidgetbriefcaseandroidemulatortogobsenyurtGeçenlerde Python ile ilgili bir şeyler ararken BeeWare isimli çalışmaya rastladım. Her yerde python ile native uygulama geliştirmek gibi bir felsefesi vardı. Eee zaten python her platformda yüklenip kullanılmıyor mu? Yoo tam olarak olay öyle değil aslında. BeeWare ürünü macOS, Linux ve Windows platformlarında native uygulama geliştirmek haricinde iOS ve Android için de destek sunan bir araçlar ve kütüphaneler topluluğu. Söz gelimi iOS ve macOS platformundaki Objective C kütüphaneleri ile Python arasında köprü görevi gören Rubicon ObjC isimli bir araç sunuyor. Java kütüphaneleri ile bir iletişim mi gerekiyor!? O zaman Rubicon Java var. Diğer yandan cross-platform için Toga isimli bir widget kütüphanesi kullanıyor. Ayrıca python projelerini tek başına çalışabilir uygulamalar haline getirmek için(standalone native application) Briefcase isimli başka bir araca sahip ki bir çoğunu birazdan kullanacağız.https://buraksenyurt.com/pingback.axdhttps://buraksenyurt.com/post.aspx?id=432505c5-d08f-4fd3-af03-a4afa325f8bc1https://buraksenyurt.com/trackback.axd?id=432505c5-d08f-4fd3-af03-a4afa325f8bchttps://buraksenyurt.com/post/beeware-ile-linux-platformunda-desktop-uygulamasi-gelistirmek-ve-android-surumunu-olusturmak#commenthttps://buraksenyurt.com/syndication.axd?post=432505c5-d08f-4fd3-af03-a4afa325f8bchttps://buraksenyurt.com/post/python-tarafinda-protobuf-protocol-buffers-serilestirmePython Tarafında ProtoBuf (Protocol Buffers) Serileştirme2020-01-14T21:00:00+00:00bsenyurt<p><img src="https://buraksenyurt.com/image.axd?picture=/2020/skynet/10/protobuf2.png" alt="" align="right" />Protocol Buffer, Google'ın yapısal verileri<em>(structured data)</em> serileştirmek için geliştirdiği bir protokol<em>(Hatta gRPC ile sıklıkla anılır)</em> Onu XML<em>(eXtensible Markup Language)</em> benzeri bir veri tanımlama formatı olarak düşünebiliriz ama çok daha az yer tutar ve serileştirme süresi çift yönlü olarak daha kısadır. Şu sıkça gördüğümüz proto uzantılı dosyaların ana fikridir.</p>
<p>Nam-ı diğer ProtoBuf örneğin ağ üzerinden gönderilecek verinin tanımını yapan bir sözleşmedir. Sözleşmenin ana unsuru ise mesajdır. Dosya içeriğine bakınca anlaşılması kolay bir mevzu iken tek başına bir anlamı yoktur, nitekim protoc isimli derleyiciden de geçmesi gerekir. Bu derleme sonucu insan gözüyle pek de okunamayan binary bir versiyon ortaya çıkar. Bunu ağ üstünden gönderebilir bir yerlerde veri olarak saklayabilir ya da ille de okumak istersek JSON, XML gibi formatlara dönüştürebiliriz.</p>
<p>Mikroservisler denince akla gelen REST, WebSockets ve GraphQL iyidir hoştur ama yüksek hız gerektiren durumlar varsa low-level RPCs<em>(Remote Procedure Calls)</em> önem kazanır. Lakin uygulanması çok kolay olmadığından bizleri over-engineering anti-pattern'ine de sürükleyebilir. Bu arada ProtoBuf'ın JSON serileştirmeli örneklerden 6 kat daha performanslı olduğu da iddia edilmiş. Detaylı bilgi için <a href="https://auth0.com/blog/beating-json-performance-with-protobuf/" target="_blank">buraya</a> bakınız.</p>
<p>Benim bu örnekteki amacım ProtoBuf serileştirme işlemini Heimdall<em>(Ubuntu 20.04)</em> üzerinde Python kodları ile kullanabilmekti. Bir veri deseni oluşturmak ve bunu çift yönlü olarak serileştirmek kafi olacaktı. ProtoBuf'ın uygulandığı tüm dillerde esas itibariyle benzer altyapı söz konusu. Olay bir proto sözleşmesinin yazılıp ilgili dil için protoc derleyicisi ile hazırlanması ve kullanımından ibaret.</p>
<h2>Hazırlıklar, Kodlama ve Çalışma Zamanı</h2>
<p>Tabii heimdall üzerinde protoc derleyicisi yüklü değildi. Yani yazıyı okuyan siz değerli okurun sisteminde de bu derleyici yüklü olmayabilir. Bu nedenle ben <a href="http://google.github.io/proto-lens/installing-protoc.html" target="_blank">şu adresteki</a> kurulum talimatlarını izledim.</p>
<pre class="brush:bash;auto-links:false;toolbar:false" contenteditable="false">PROTOC_ZIP=protoc-3.7.1-linux-x86_64.zip
curl -OL https://github.com/protocolbuffers/protobuf/releases/download/v3.7.1/$PROTOC_ZIP
sudo unzip -o $PROTOC_ZIP -d /usr/local bin/protoc
sudo unzip -o $PROTOC_ZIP -d /usr/local 'include/*'
rm -f $PROTOC_ZIP
protoc --version</pre>
<p>Örnekte birde protobuf dosyamız mevcut elbette. Yani ağ üzerinden koşturacağımız veri desenimiz. Ben örnek olarak bir görev bilgisini tasarlamaya çalıştım. Görevin başlığı, açıklaması, durumu gibi bilgilerin yer aldığı bir veri modeli...</p>
<pre class="brush:js;auto-links:false;toolbar:false" contenteditable="false">syntax="proto3"; // Kullandığımız ProtoBuf versiyonu
package company;
// görev durumunu tutacağımız enum sabiti
enum State{
PLANNED=0;
IN_PROGRESS=1;
DONE=2;
}
// ana tipimiz Job
// içinde n sayıda Task içerebilir ki o da bir sözleşme tipidir
// niteliklere atanan sayılar binary encode edilen çıktıdaki alanları işaret eden benzersiz sayılardır.
// Bir nevi eşleştirme veya yer bulma tekniği.
message Job{
int32 job_id=1;
string title=2;
// İşteki görevleri tanımlayan tipimiz
message Task{
int32 task_id=1;
string title=2;
string description=3;
State state=4; //enum sabiti tipinden
}
repeated Task tasks=3; //Task tipinin tekrarlanabileceğini belirtiyor
}</pre>
<p>Başta da belittiğimiz üzere yazılan bu proto dosyasının pyhton çalışma zamanı ortamında kullanılabilmesi için bir derleme işleminden geçmesi gerekiyor. Bunu aşağıdaki terminal komutları yardımıyla gerçekleştirebiliriz. Sonuç olarak jobs_pb2.py isimli bir dosya üretilecektir. Bu paket izleyen app.py içerisinde kullanılmaktadır. Yorum satırlarını takip edelim ;)</p>
<pre class="brush:bash;auto-links:false;toolbar:false" contenteditable="false">protoc -I=. --python_out=. ./jobs.proto</pre>
<p>Gelelim protobuf içeriğini kullanarak örnek serileştirme ve ters-serileştirme işlemlerini yapan Python kodlarımızın yer aldığı app nesnesine.</p>
<pre class="brush:py;auto-links:false;toolbar:false" contenteditable="false"># encoding:utf-8
import jobs_pb2 as Job # Protoc dosyasından üretilen paketi ekledik
# Yeni bir Job nesnesi tanımlayıp içine birkaç Task ekliyoruz
job = Job.Job()
job.job_id = 1802234
job.title = "Şube personeli fatura onay sürecine olarak belge yükleyebileceğim bir ekran istiyorum."
task1 = job.tasks.add()
task1.task_id = 1
task1.title = "Ekran Tasarımı"
task1.description = "Fatura yükleme ekranının tasarımı"
task1.state = Job.State.Value("IN_PROGRESS")
task2 = job.tasks.add()
task2.task_id = 2
task2.title = "Fatura Şema Tasarımı"
task2.description = "Fatura içeriği için gerekli protoc içeriğinin tasarımı"
task2.state = Job.State.Value("PLANNED")
# print(job) # Ekrana çıktıyı basalım
# Job içeriğini jobs.data isimli dosya içine serileştiriyoruz
with open("./jobs.data", "wb") as file:
file.write(job.SerializeToString())
print("İçerik Serileştirildi...")
print(job.SerializeToString())
print()
incoming_job = Job.Job() # yeni bir job nesnesi oluşturalım
# jobs.data içeriğini okuyup incoming_job içerisine ters serileştirelim
with open("./jobs.data", "rb") as file:
incoming_job.ParseFromString(file.read())
print("Şimdi Dosyadan Ters Serileştirildi")
print(incoming_job)</pre>
<p>Yazdığımız örneği aşağıdaki terminal komutu ile çalıştırabilir ve sonuçları irdeleyebiliriz.</p>
<pre class="brush:bash;auto-links:false;toolbar:false" contenteditable="false">python3 app.py</pre>
<p><img src="https://buraksenyurt.com/image.axd?picture=/2020/skynet/10/Screenshot_1.png" alt="" /></p>
<p>Esasında örnekte protobuf olarak tasarlanmış bir nesnenin python ile serileştirme işlemlerinde nasıl kullanıldığını incelemiş olduk. Gerçek hayat örneği için bu kurguyu bir servisin arkasına taşımak çok daha doğru olur. Örneğin Flask ile bir servis geliştirip istemci ile haberleşilen veriler için JSON yerine protobuf kullanımı örneklenebilir. Bu pekala sizin için güzel bir ödev de olabilir :) O halde ne duruyorsunuz!? Haydi başlayın.</p>
<p>Örneğin tüm kodlarına ve ilk notlarına <a href="https://github.com/buraksenyurt/skynet/tree/master/No%2010%20-%20Protocol%20Buffers%20with%20Python/src" target="_blank">Skynet github reposu</a>ndan erişebilirsiniz. Tekrardan görüşünceye dek hepinize mutlu günler dilerim.</p>2020-01-14T21:00:00+00:00pythonprotobufrestwebsocketsprotocolbsenyurtProtocol Buffer, Google'ın yapısal verilerin (structured data) serileştirilmesi için geliştirdiği bir protokol. gRPC ile sıklıkla anılır. XML benzeri düşünebiliriz ama çok daha az yer tutar ve serileştirme süreleri hızlıdır. Şu sıkça gördüğümüz proto uzantılı dosyaların ana fikridir. Nam-ı diğer ProtoBuf örneğin ağ üzerinden gönderilecek verinin tanımını yapan bir sözleşmedir. Sözleşmenin ana unsuru mesajdır. Dosya içeriğine bakınca anlaşılması kolay bir mevzu. Tek başına bir anlamı yoktur. protoc isimli derleyiciden geçmesi gerekir. Bu derleme sonucu insan gözüyle pek de okunamayan binary bir türev ortaya çıkar. Bunu ağ üstünden gönderebilir, bir yerlerde veri olarak saklayabilir ya da ille de okumak istersek JSON, XML gibi formatlara dönüştürebiliriz.https://buraksenyurt.com/pingback.axdhttps://buraksenyurt.com/post.aspx?id=4075c996-a465-4a61-948b-b3435c92bc210https://buraksenyurt.com/trackback.axd?id=4075c996-a465-4a61-948b-b3435c92bc21https://buraksenyurt.com/post/python-tarafinda-protobuf-protocol-buffers-serilestirme#commenthttps://buraksenyurt.com/syndication.axd?post=4075c996-a465-4a61-948b-b3435c92bc21https://buraksenyurt.com/post/bir-python-uygulamasini-git-teknigi-ile-azure-platformuna-tasimakBir Python Uygulamasını git Tekniği ile Azure Platformuna Taşımak2019-09-09T12:30:00+00:00bsenyurt<p><img style="float: right;" src="https://buraksenyurt.com/image.axd?picture=/2019/08/41/ahchto.png" alt="" />Rey evrenin taaa bir ucundan kalkıp ahch-to gezegenine gelmiş ve Jedi ustasının onu eğitmesini istemişti. Galaksinin bir kez daha Luke Skywalker'a ihtiyacı vardı. Uzun zamandır inzivada olan Luke ise Kylo Ren'den sonra buna pek gönüllü değildi. İzleyenler bilir. Luke, neredeyse sadece sudan ibaret ahch-to gezegenindeki bir adada, eski Jedi tapınağında yaşamını sürdürmektedir<em>(Sevgili <a href="https://eksisozluk.com/entry/78992085" target="_blank">ekşi sözlük yazarı John Harrison</a> bu girişi beğenmeyecektir ama olsun :D )</em></p>
<p>Peki bu gezegeninin gerçekte nerede olduğunu biliyor musunuz?</p>
<p>Ahch-to, İrlanda'nın Kerry ilinin yaklaşık 11.6 km batısında yer alan Skellig Michael isimli bir ada aslında. Atlantik okyanusunda yer alan bu küçük ada üstünde 6ncı yüzyılda kurulan bir de manastır bulunuyor. Zaten filmde de Luke'un inzivaya çekildiği yer benzer dini ve mistik karakteristikliklere sahip. Tarihi yapısını önemli derecede korumuş ve UNESCO tarafından 1996 yılında Dünya Mirasları arasına alınmış bu adanın benim için anlamı ise yeni bir macera.</p>
<p>Nitekim o cumartesi gecesi Westworld'ü<em>(Ubuntu 18.04, 64bit)</em> kenara koymuş çok sık kullanılan Azure öğretilerinden birisini ahch-to üstünde deniyordum. Öğretinin temel amacı git yardımıyla Azure üzerinden deployment işlemi başlatabilmekti. Ben bunu bir python uygulaması için denemek istiyordum. Bu sefer işim biraz daha zorluydu. Çünkü <a href="https://github.com/buraksenyurt/saturday-night-works" target="_blank">cumartesi gecesi çalışmaları</a>nın ikinci fazını yapmayı planladığım ahch-to<em>(Mac Mini, High Sierra)</em> adasındaydım. Derken düğmeye bastım ve öğretiyi uygulamaya koyuldum. Pek tabii ahch-to gezegeninde eksikler vardı...</p>
<h2>Ön Gereksinimler ve Kurulumlar</h2>
<p>Geliştireceğimiz örnek python flask paketini kullanan basit bir web uygulaması olacak. ahch-to sisteminde python'un 2.7 sürümü mevcut<em>(ki bu sierra sürümü ile yüklü olarak geldi)</em> lakin ben 3 üzeri bir versiyon kullanmak istiyorum. Bu nedenle homebrew paket yönetim aracından yararlanarak yeni bir kurulum gerçekleştirdim<em>(Tabii homebrew de sistemde yoktu. Nasıl kurulacağının keşfini size bırakıyorum)</em></p>
<pre class="brush:bash;auto-links:false;toolbar:false" contenteditable="false">brew update
brew install python</pre>
<h3>Azure CLI Kurulumu</h3>
<p>Paket yöneticisini kurduktan sonra Azure tarafındaki işlemler için yararlanılan CLI<em>(command-line interface)</em> aracını da kurmak gerekiyor. Onu kurmak için ilk terminal komutunu kullanabiliriz. Pek tabi kurulum yeterli değil. Azure tarafı ile konuşabilmek için login işlemini de yapmamız lazım. İkinci terminal komutu bunun için<em>(Bu aşamada Azure'da bir hesabınız olduğunu varsayıyorum)</em></p>
<pre class="brush:bash;auto-links:false;toolbar:false" contenteditable="false">brew install azure-cli
az login</pre>
<p><img src="https://buraksenyurt.com/image.axd?picture=/2019/08/41/credit_1.png" alt="" /></p>
<h3>Azure Deployment Hazırlıkları</h3>
<p>Uygulamayı Azure tarafına deploy edebilmek için de yapılması gerekenler var. Sırasıyla deployment user, resource group, service plan ve son olaraktan da bir web app oluşturmalıyız. Bunlar için aşağıdaki terminal komutlarını kullanarak ilerleyebiliz.</p>
<pre class="brush:bash;auto-links:false;toolbar:false" contenteditable="false">as webapp deployment user set --user-name dpyl-usr-buraks --password <azure kurallarına uyan bir şifre>
az group create --name rg-todoshero --location westeurope
az appservice plan create --name plan-todoshero --resource-group rg-todoshero --sku B1 --is-linux
az webapp create --resource-group rg-todoshero --plan plan-todoshero --name todosherowebapp --runtime "PYTHON|3.7" --deployment-local-git</pre>
<p>İlk satırda dply-usr-buraks isimli bir kullanıcı tanımlıyoruz. Deployment işlemlerini bu kullanıcı yapacak. İkinci satırda veri tabanı, servis planlaması, kurulumu yapılacak uygulamalar gibi bu işimizle ilgili kaynakları grupladığımız bir tanımlama bulunuyor<em>(Örneğin Resource Group'u platformdan kaldırdığımızda bu grup altında hazırladığımız ne kadar Azure enstrümanı varsa silinecektir)</em> İşimizle ilgili kaynakları tek noktadan yönetmek için açtığımızı düşünebilirsiniz. Üçüncü komutta bir servis planı oluşturmaktayız. Burada basic ödeme şartlarına göre oluşturulan ve linux tabanlı docker container kullanılan bir plan söz konusu. Son terminal komutu ile todosherowebapp isimli bir web uygulaması oluşturuyoruz. Bu servis uygulaması biraz önce oluşturlan servis planına göre hazırlanacak ve Python 3.7 sürümü ile çalışacak. Sonda yer alan --deployment-local-git parametresi ile dağıtım planımızı<em>(git ile yapacağımızı)</em> belirtiyoruz.</p>
<p>Terminalden çalıştırdığım komutlar başarılı olunca aşağıdaki sonuçla karşılaştım.</p>
<p><img src="https://buraksenyurt.com/image.axd?picture=/2019/08/41/credit_3.png" alt="" /></p>
<p>Uygulamanın web adresi todosherowebapp.azurewebsites.net olarak belirlenirken, github repository adresi de https://dply-usr-buraks@todosherowebapp.scm.azurewebsites.net/todosherowebapp.git şeklinde oluştu. Görüldüğü üzere varsayılan bir hoş geldin sayfamız bile var. Hatta doğrudan dokümantasyonlarına ulaşıp ilk geliştirmelerimizi yapabiliriz de <em>(Şu an aktif değil. Malum kullanılmayacak bir servis olacağından sildim)</em></p>
<p><img src="https://buraksenyurt.com/image.axd?picture=/2019/08/41/credit_4.png" alt="" /></p>
<h2>Uygulamada Yapılanlar</h2>
<p>Öncelikle local ortamımızda neler yaptığımız bir bakalım. Python tarafındaki örneğimiz son derece basit. Klasör ve dosya ağacı aşağıdaki gibi oluşturulabilir. Kritik noktalardan birisi requirements.txt dosya içeriği.</p>
<pre class="brush:bash;auto-links:false;toolbar:false" contenteditable="false">cd src
mkdir todayshero
touch todayshero/app.py
touch todayshero/requirements.txt
touch todayshero/.gitignore</pre>
<p>Python kodumuzu içeren app.py aşağıdaki gibi yazılabilir. Uygulama, web tarafından route adrese gelen taleplere karşılık içindeki heros isimli listeden rastgele isim döndürmek üzere tasarlanmış durumda.</p>
<pre class="brush:py;auto-links:false;toolbar:false" contenteditable="false">from flask import Flask # basit web özelliklerini kazandırmak için
from random import seed
from random import randint # Rastgele sayı üretmek için
app = Flask(__name__)
# bir kahraman listemiz var
heros = ["thor", "wolverine", "iron man", "hulk", "doctor strane"
"kira", "superman", "batman", "wonder woman"]
# kök adrese talep geldiğinde devreye giren metodumuz
@app.route("/")
def getRandomHero():
randomIndex = randint(0, len(heros)-1) #0 ile listedeki eleman sayısı aralığında rastgele bir tam sayı üretiyoruz
return '<h2>'+heros[randomIndex]+'</h2>' # sonucu html olarak dönüyoruz
</pre>
<p>Requirements.txt, Azure platformunun Python ortamlı deploy işlemi için kullanacağı bir doküman. Bu dosya içerisine yazılan paketler, azure deploy işlemi sırasında pip ile uzak sunucu ortamına yüklenmeye çalışılır. Örneğe göre son derece sade bir içeriğimiz var (:</p>
<pre class="brush:plain;auto-links:false;toolbar:false" contenteditable="false">Flask==1.0.2</pre>
<blockquote>
<p>Bu arada ahch-to üzerindeki denemeler için flask paketini geliştirme ortamına da yüklememiz gerekiyor.</p>
<pre class="brush:bash;auto-links:false;toolbar:false" contenteditable="false">pip3 install flask</pre>
</blockquote>
<h2>Çalışma Zamanı<em>(Local ortamda)</em></h2>
<p>Kod tarafı hazır olduğuna göre uygulamayı çalıştırıp sonuçlarını değerlendirebiliriz. İlk olarak local makine üzerinden aşağıdaki terminal komutu ile ilerleyelim.</p>
<pre class="brush:bash;auto-links:false;toolbar:false" contenteditable="false">FLASK_APP=app.py flask run</pre>
<p><img src="https://buraksenyurt.com/image.axd?picture=/2019/08/41/credit_2.png" alt="" /></p>
<p>Sayfaya yeni talepler gönderdikçe farklı kahramanlar ile karşılaşmamız gerekiyor. Bu basit uygulama kodu list içeriğinden seçtiği rastgele bir karakterin adını ekrana yazdırmakla görevli<em>(git ve azure ikilisinin bir arada kullanılması üzerine yoğunlaştığımızdan mümkün mertebe basit bir örnek kullanıyoruz)</em></p>
<h2>Çalışma Zamanı<em>(Git Deploy)</em></h2>
<p>Artık programın çalıştığından eminiz. Dolayısıyla asıl dağıtım operasyonuna başlayabiliriz. Bunu git aracılığıyla yapmak için aşağıdaki terminal komutlarını çalıştırmamız yeterli<em>(todoshero klasörü altında)</em></p>
<pre class="brush:bash;auto-links:false;toolbar:false" contenteditable="false">git init
git remote add azure https://dply-usr-buraks@todosherowebapp.scm.azurewebsites.net/todosherowebapp.git
git add .
git commit -m "Application has been added"
git push azure master</pre>
<p>Standart git komutları ile uygulamayı azure reposuna deploy ettik. İlk olarak initialize işlemi var. Sonra uzak repo adresini ekliyoruz. Tüm kod dosyalarını . ile alıp commit ettikten sonra push çağrısı ile değişikliklerimizi yolluyoruz.</p>
<p>push işlemini takiben azure sitesine tekrar gittiğimde python uygulamasının başarılı bir şekilde etkinleştiğini görmemiz lazım. Aşağıdakine benzer bir durum olmalı.</p>
<p><img src="https://buraksenyurt.com/image.axd?picture=/2019/08/41/credit_5.png" alt="" /></p>
<p>Hatta Azure portaline baktığımızda hem oluşturulan resource group içeriğini hem de yaptığımız son push işlemlerini de görebilmeliyiz.</p>
<p><img src="https://buraksenyurt.com/image.axd?picture=/2019/08/41/credit_6.png" alt="" /></p>
<p><img src="https://buraksenyurt.com/image.axd?picture=/2019/08/41/credit_7.png" alt="" /></p>
<p>Hepsi bu! :) Siz de farklı uygulama geliştirme ortamları için<em>(ruby, .net core, node.js vb)</em> aynı kurguyu gerçekleştirmeyi deneyebilirsiniz.</p>
<h2>Ben Neler Öğrendim?</h2>
<p>Yazılım ürünlerinin resmi sitelerinde yer alan bu tip adım adım serileri konuyu artık çok iyi öğretiyor. Mesleğe ilk başladığım zamanlarda neredeyse yok denecek kadar azdı. Hatta MSDN'in bile ilk yıllarındaki içerik kalitesi oldukça karışıktı. Ancak yeni nesil bu konuda epey şanslı. Peki <a href="https://github.com/buraksenyurt/saturday-night-works" target="_blank">saturday-night-works</a> çalışmalarının <a href="https://github.com/buraksenyurt/saturday-night-works/tree/master/No%2041%20-%20Python%20to%20Azure%20With%20Git" target="_blank">birinci fazının bu son örneği</a>nde ben neler öğrendim dersiniz.</p>
<ul>
<li>brew ile macOS platformuna paket yüklemeyi</li>
<li>azure CLI ile deployment user, resource group, service plan ve web app oluşturmayı</li>
<li>git komutları ile kodu azure'a atmayı</li>
<li>requirements.txt dosya içeriğinin ne işe yaradığını</li>
</ul>
<p>Böylece geldik bir maceramızın daha sonuna. Tekrardan görüşünceye dek hepinize mutlu günler dilerim.</p>2019-09-09T12:30:00+00:00pythongitazurecontinuous integrationcontinuous deploymentci/cdcliazure clibrewmacosappledeployment userresource groupservice plandockercloud computingcloud servicesflaskbsenyurtÇok sık kullanılan Azure öğretilerinden birisi bu. Amaç git yardımıyla Azure üzerinde deployment işlemi başlatmak. Ben bunu python ile denemek istedim. Bu sefer işim biraz daha zorlu. Nitekim WestWorld(Ubuntu 18.04, 64bit) topraklarını bir süreliğine terk ettim. Artık ahch-to(Mac Mini, High Sierra) adasındayım. Bu nedenle sistemde bazı şeyler eksik gibi görünüyor.https://buraksenyurt.com/pingback.axdhttps://buraksenyurt.com/post.aspx?id=024b529b-46fd-446b-a93c-fd98759de5f80https://buraksenyurt.com/trackback.axd?id=024b529b-46fd-446b-a93c-fd98759de5f8https://buraksenyurt.com/post/bir-python-uygulamasini-git-teknigi-ile-azure-platformuna-tasimak#commenthttps://buraksenyurt.com/syndication.axd?post=024b529b-46fd-446b-a93c-fd98759de5f8https://buraksenyurt.com/post/Python-Loglamada-ELK-KullanımıPython Loglamada ELK Kullanımı2019-04-27T19:32:00+00:00bsenyurt<p><img style="float: right;" src="https://buraksenyurt.com/image.axd?picture=/2019/04/20/elk.png" alt="" />Laptop ekranına kitlenmiş error seviyesindeki logları inceliyordum. HTTP 400 en sevdiğim<em>(yazar burada kendisiyle dalga geçiyor)</em> ama çözmekte en çok zorlandıklarımdan birisiydi. Neyse ki monitör ettiğimiz araç bize güzel detaylar veriyordu. Pek tabii iş yoğunluğundan olsa gerek, üzerinde geliştirme yaptığımız ürünlerin bazı kurgularını inceleme fırsatı bulamıyordum. Lakin zaman zaman takım arkadaşlarımla veya mimari ekiptekilerle yaptığım konuşmalarda havada uçuşan, daha önceden duyduğum ama derinlemesine bilgi sahibi olmadığım kelimelere rastlıyordum.</p>
<p>ELK kısaltmasını ilk telafüz ettiklerinde zihnimde hiçbir şey canlanmamıştı. Bilmediğim ve öğrenmem gereken bir konu daha ortaya çıkmıştı işte. 2019 yılına girerken aldığım karar doğrultusunda öncelikle sağdan soldan adını duyduğum enstrümanları anlamaya çalışacak ve bunları <a href="https://github.com/buraksenyurt/saturday-night-works" target="_blank">saturday-night-works</a> altında kabataslak notlarla deneyimleyecektim. Sanırım bu yıl için aldığım en doğru karardı diyebilirim. Şimdi bunun nimetlerini toplamak üzere bazı çalışmaları bloğumda kendime not olarak düşüyorum. Sırada ELK kelimesinin derin anlamını öğrenmek var. Tabii onu Kanada'nın simgelerinden biri olan 800 kiloluk koca bir geyik türü olarak düşünmüyoruz. En azından şimdilik...</p>
<p>ELK...Yani Elasticsearch, Logstash ve Kibana üçlüsü. Mikroservislerde log stratejisi olarak sıklıkla kullanılıyorlar. Tabii bazı ürünlerde çeşitli performans sıkıntıları nedeniyle tercih edilmediklerine dair yazılara da rastlamadım değil. Ancak şirketimizde de kullanılan bir düzenek olduğu için onu anlamamın en iyi yolu denemekten geçiyordu. Aslında düzenek son derece basit. İzlemek istediğimiz uygulamalara ait log bilgileri logstash tarafından dinlenip JSON formatına dönüştürülüyor ve Elasticsearch'e basılıyor. Elasticsearch'e alınan log kayıtları da Kibana arayüzü ile izleniyor.</p>
<p>Benim amacım ELK üçlüsünü WestWorld'de<em>(Ubuntu 18.04, 64bit)</em> deneyimlemek ve loglama işini yapan uygulama tarafında basit bir Python kodunu kullanmak. WestWorld'ün uzun denemeler sonrası bozulan ekosistemini daha da dağıtmak istemediğimden Elasticsearch ve Kibana tarafı için Docker Container'larını kullanacağım. Kabaca aşağıdaki gibi bir senaryonun söz konusu olduğunu ifade edebilirim.</p>
<p><img src="https://buraksenyurt.com/image.axd?picture=/2019/04/20/Cover_1.jpg" alt="" /></p>
<h2>Örnek Uygulama Kodları</h2>
<p>Aşağıdaki içeriğe sahip ve izlemek için log üreten çok basit bir Python kod dosyamız var. Dosyanın başındaki import bildirimlerinden de görüleceği üzere logging, time ve random isimli modüller kullanılıyor. Built-in logging modülünden yararlanılarak appLogs isimli dosyaya appende modda log atılacağı belirtiliyor. Logun mesaj ve tarih formatları da basicConfig metodunun son parametreleri ile tanımlanıyor.</p>
<pre class="brush:py;auto-links:false;toolbar:false" contenteditable="false"># Python tarafında logging sistemi built-in olarak gelmektedir.
import logging
import time
import random
logging.basicConfig(filename="appLogs.txt",
filemode='a',
format='%(asctime)s %(levelname)s-%(message)s',
datefmt='%Y-%m-%d %H:%M:%S')
logging.warning('Sistem açılışında tutarsızlık')
for i in range(0, 10): # 10 tane log atıyoruz
# zamanı 0 ile 4 arası rastgele sürelerde duraksatıp log attırıyoruz
d = random.randint(0, 4)
time.sleep(d)
if d == 3:
logging.exception('Fatal error oluştu')
else:
logging.warning('Sistemde yavaşlık var...')
logging.critical('Sistem kapatılamıyor')
</pre>
<h2>Kurulumlar </h2>
<p>Şimdi bu kodun logları için gerekli ELK düzeneğini kuracağız. Gerekenleri aşağıdaki gibi maddeleştirmeye çalıştım.</p>
<h3>Elasticsearch ve Kibana Tarafı</h3>
<p>Elasticsearch'ün Docker kurulumu ve başlatılması için,</p>
<pre class="brush:html;auto-links:false;toolbar:false" contenteditable="false">docker pull docker.elastic.co/elasticsearch/elasticsearch:6.6.0
docker run -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" docker.elastic.co/elasticsearch/elasticsearch:6.6.0</pre>
<p>Kibana'ya ait Docker imajı için,</p>
<pre class="brush:bash;auto-links:false;toolbar:false" contenteditable="false">docker pull docker.elastic.co/kibana/kibana:6.6.0
sudo docker run --net=host -e "ELASTICSEARCH_URL=http://localhost:9200" docker.elastic.co/kibana/kibana:6.6.0</pre>
<p>terminal komutlarını çalıştırmak yeterli. Ben örneği denediğim dönemde stabil olan versiyonları kullandım ancak siz kendi denemelerinizi yaparken konuları google'layıp doğru sürümleri kullanmaya çalışın. Bu arada Elasticsearch ve Kibana container'ları çalıştıktan sonra aşağıdaki adreslere gidip aktif hale gelip gelmediklerini kontrol etmekte yarar var.</p>
<pre class="brush:plain;auto-links:false;toolbar:false" contenteditable="false">http://localhost:9200/ -> Elasticsearch
http://localhost:5601/status -> Kibana</pre>
<p>Elastichsearch çalışır durumda.</p>
<p><img src="https://buraksenyurt.com/image.axd?picture=/2019/04/20/Cover_2.png" alt="" /></p>
<p>Monitoring aracımız olan Kibana'da öyle.</p>
<p><img src="https://buraksenyurt.com/image.axd?picture=/2019/04/20/Cover_3.png" alt="" /></p>
<h3>Logstash Tarafı</h3>
<p>Logstash tarafı için öncelikle <a href="https://www.elastic.co/downloads/logstash" target="_blank">şu adresten</a> ilgili içeriği indirip kurmak gerekiyor <em>(Docker imajı yerine neden bu yolu tercih ettim şu anda hatırlamıyorum)</em> Bundan sonra python uygulamamızın ürettiği logları takip etmesi için aşağıdaki içeriğe sahip bir konfigurasyon dosyasına ihtiyacımız var. Dosyayı etc/logstash/conf.d altına oluşturuyoruz. Bu klasör içerisindeki conf uzantılı dosyalar logstash servisi tarafından takip edilmekte. Böylece logstash hangi logları takip edeceğini bilecek ve onları Kibana tarafına gönderecek.</p>
<blockquote>
<p>Bu ve benzeri konfigurasyon dosyalarının logstash servisi tarafından otomatik olarak ele alınabilmesi için etc/logstash/conf.d klasörü altında konuşlandırılmaları önemli. Tabii Ubuntu için geçerli bir durum olduğunu ifade edelim.</p>
</blockquote>
<p>logstash-python.conf</p>
<pre class="brush:xml;auto-links:false;toolbar:false" contenteditable="false">input{
file{
path => "/home/burakselyum/Development/saturday-night-works/No 20 - Python Logging with ELK/appLogs.txt"
start_position => "beginning"
}
}
filter
{
grok{
match => {"message" => "%{TIMESTAMP_ISO8601:timestamp} %{LOGLEVEL:log-level}-%{GREEDYDATA:message}"}
}
date {
match => ["timestamp", "ISO8601"]
}
}
output{
elasticsearch{
hosts => ["localhost:9200"]
index => "index_name"}
stdout{codec => rubydebug}
}</pre>
<p>Dosyanın üç ana kısımdan oluştuğunu söyleyebiliriz. Log dosya kaynağına ait bilgilerin olduğu input, dosya içinden bilginin nasıl alınacağına dair filter ve dönüşüm sonrası içeriğin nereye basılacağının belirtildiği output. path özelliğinin değeri logstash'in izleyeceği dosyayı ifade etmektedir. grok elementinin içeriği de önemlidir. Nitekim text dosyasına atılan standart log mesajlarını nasıl yakalayacağına dair bir desen tanımlamaktadır. Kısacası Grok filtreleme aracı ile text dosyaları gibi hedeflere atılan unstructured log bilgilerini parse etmenin oldukça kolaylaştığını ifade edebiliriz. Sistem logları, Apache logları, SQL logları vb bir çok enstrümanın loglama yapısı buradaki desenlere uygundur zaten. output kısmında dikkat edileceği üzere Elasticsearch'ün host bilgisi yer alıyor. </p>
<h2>Çalışma Zamanı</h2>
<p>Tabii düzeneğin işlerliğini görebilmek adına en az bir kereliğine de olsa main.py dosyasını çalıştırmamız lazım. Bunu aşağıdaki terminal komutu ile yapabiliriz.</p>
<pre class="brush:bash;auto-links:false;toolbar:false" contenteditable="false">python3 main.py</pre>
<p>Bu arada logstash servisinin aktif olduğundan emin olmak gerekiyor ki yazılan log'lar takip edilsin. Eğer çalışmıyorsa Logstash servisini başlatmak için terminalden</p>
<pre class="brush:bash;auto-links:false;toolbar:false" contenteditable="false">service logstash service</pre>
<p>komutunu yürütmek yeterli.</p>
<h2>Kibana Monitoring</h2>
<p>logstash etkinleştirildikten sonra Kibana'ya gidip yeni bir index oluşturabiliriz. index_name* ve @timestamp field'ını seçerek ilerlediğimizde python uygulaması tarafından üretilen logların yakalandığını görürüz.</p>
<p><img src="https://buraksenyurt.com/image.axd?picture=/2019/04/20/Cover_4.png" alt="" /></p>
<blockquote>
<p>Visualize kısmını kurcalayarak çeşitli tipte grafikler hazırlayıp Dashboard'u etkili bir monitoring aracı haline dönüştürmemiz de mümkün.</p>
</blockquote>
<h2>Docker Tarafı</h2>
<p>Testler sonrası Docker tarafında ihtiyaç duyabileceğimiz komutlar da olabilir. Söz gelimi Container'ların listesini görmek ve durdurmak için aşağıdaki komutlardan yararlanabiliriz ki çalışma sırasında benim çok işime yaradılar <em>(Container ID'ler farklılık gösterecektir)</em></p>
<pre class="brush:bash;auto-links:false;toolbar:false" contenteditable="false">sudo docker ps -a
sudo docker stop 3402e6aaced3</pre>
<h2>Ben Neler Öğrendim</h2>
<p>Cumartesi gecesi çalışmalarının <a href="https://github.com/buraksenyurt/saturday-night-works" target="_blank">20nci bölümünü de bu şekilde tamamlamıştım</a>. Bu macerada da öğrendiklerim oldu. </p>
<ul>
<li>ELK üçlemesinin nasıl bir çözüm sunduğunu</li>
<li>Mikro servis dünyasında nasıl kurgulanabileceklerini</li>
<li>Ubuntu platformunda Docker imajlarından nasıl yararlanılabileceğini</li>
<li>Python kodundan logging paketini kullanarak nasıl log atılabileceğini</li>
<li>Elastichsearch ve Kibana'nın docker imajları ile çalışmayı</li>
<li>logstash config dosyasında ne gibi tanımlamalara yer verildiğini</li>
</ul>
<p>Böylece geldik bir maceramızın daha sonuna. Sizde merak ettiklerinizi öğrenmek için kendinize vakit ayırın. Tekrardan görüşünceye dek hepinize mutlu günler dilerim.</p>2019-04-27T19:32:00+00:00elkelasticsearchkibanalogstashpythonloggingdockerubuntujsongorkbsenyurtELK yani Elasticsearch, Logstash ve Kibana üçlüsü. Microservis'lerde log stratejisi olarak sıklıkla kullanılıyorlar. Uygulamaların log bilgileri logstash tarafından dinlenip JSON formatına dönüştürülüyor ve Elasticsearch'e basılıyor. Elasticsearch'e alınan log'lar Kibana arayüzü ile izleniyor. Benim amacım ELK üçlüsünü WestWorld'de _(Ubuntu 18.04, 64bit)_ deneyimlemek ve loglama işini yapan uygulama tarafında basit bir Python kodunu kullanmak. WestWorld'ün uzun denemeler sonrası bozulan ekosistemini daha da dağıtmak istemediğimden Elasticsearch ve Kibana tarafı için Docker Container'larını kullanmak istiyorum. Kabaca aşağıdaki gibi bir senaryo söz konusu.https://buraksenyurt.com/pingback.axdhttps://buraksenyurt.com/post.aspx?id=7b0e3e2b-9ff9-48c9-9134-092f1778eea10https://buraksenyurt.com/trackback.axd?id=7b0e3e2b-9ff9-48c9-9134-092f1778eea1https://buraksenyurt.com/post/Python-Loglamada-ELK-Kullan%C4%B1m%C4%B1#commenthttps://buraksenyurt.com/syndication.axd?post=7b0e3e2b-9ff9-48c9-9134-092f1778eea1https://buraksenyurt.com/post/bir-aws-elastic-beanstalk-macerasiAWS Elastic Beanstalk Macerası2018-02-16T05:00:00+00:00bsenyurt<p><img style="float: right;" src="https://buraksenyurt.com/image.axd?picture=/2018/01/ebpython_robin.gif" alt="" />Merhaba Arkadaşlar,</p>
<p>Geçenlerde sıkıldığım bir ara kendimi Google'da "How To Draw..." araması yaparken buldum. <a href="http://www.drawinghowtodraw.com/stepbystepdrawinglessons/2016/10/draw-cute-kawaii-chibi-robin-dc-comics-batman-robin-easy-steps-drawing-lesson-kids/" target="_blank">Bir internet sitesinde</a> DC Comics'in Robin karakterini nasıl çizebileceğimizi anlatan içerik ilgimi çekmişti. Geometri bilgisini iyi kullandığı için anlaşılırdı. Tabii önemli bir eksiğim vardı...Yetenek. Sonuçları sizlerle paylaşmayı çok tercih etmiyorum ama yandaki Robin'in kafasının pek yakınlarından geçemediğimi gönül rahatlığıyla itiraf edebilirim. Dolayısıyla google aramasını ve internet sayfasını kapatıp tekrardan az buçuk anlamaya çalıştığım yazılım dünyasına döndüm.</p>
<p>Aslında bazen öğrenmek istediğimiz konuyu adım adım ve her adımında da tane tane anlatan bir dokümanı takip ederiz. Ama çalıştığımız ortamlar her zaman için bir yerlerde sorunlarla karşılaşmamıza neden olabilirler. Geçtiğimiz cumartesi günü de benzer sorunlarla karşılaştım. Amacım Amazon'un <a href="http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/create-deploy-python-django.html?refid=em_68105" target="_blank">şu adreste</a> yayınladığı dokümanı takip ederek Elastic Beanstalk üzerine Django ile oluşturulmuş bir web uygulamasını taşıyıp Doğu Amerika kıtasındaki herhangibir Elastic Compute Cloud(Amazon EC2) sistemi üzerinden canlı yayına almaktı. İlk başlarda kolay giden adımlar özellikle sonlara doğru çeşitli sürprizlerle karşılaşmama neden oldu.</p>
<p>Her şey o Cuma günü AWS'de açmış olduğum hesapla neler yapabileceğime bakarken başladı. Bir süre öncesinde <a href="https://buraksenyurt.com/post/AWS-Lambda-Uzerinde-Net-Core-Kosturmak" target="_blank">Amazon Lambda hizmetini incelemiş</a> ve .Net Core ile kullanabildiğimi gördükten sonra epey keyif almıştım. Şimdiki hedefim Elastic Beanstalk ürünüydü. Kısaca Platform as a Service gibi konumlanan bu ürün sayesinde, çeşitli platformları Amazon EC2 örnekleri ile çalışacak şekilde hazırlayabiliyoruz. Platform anlamında oldukça geniş bir ürün yelpazesi de söz konusu. <a href="http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/concepts.platforms.html" target="_blank">Buradaki adresten</a> detaylarını öğrenebileceğinize gibi .Net Core'dan Go'ya, Python'dan Java'ya, Ruby'den Php'ye, Node.js'ten Docker'a kadar pek çok uygulama için hazır ortamlar söz konusu.</p>
<p>Buradaki hazırlıklarda Infrastructure as a Service gibi konumlanan Amazon EC2 tarafını da pek düşünmemize gerek kalmıyor esasında. Bu noktada EB'nin başarılı bir Deployment aracı olduğunu da ifade edebiliriz. EB'yi kullanırken Amazon Web Console üzerinden bir kaç tıklama ile bir platformu ayağa kaldırıp yayına almamız mümkün. İşte o Cuma akşamı bunu denemiştim. Şekilden de görüleceği gibi üzerinde Python 3.6 ortamı kurulu olan 64bitlik bir Linux makine emrime amadeydi. </p>
<p><img src="https://buraksenyurt.com/image.axd?picture=/2018/01/ebpython_0_1.gif" alt="" /></p>
<p>Hatta hazır şablon olarak gelen bir giriş sayfası da bulunuyordu<em>(What's Next? kısmı da oldukça dikkat çekiciydi. Django ve Flesk hemen dikkatimi çekmişlerdi)</em></p>
<p><img src="https://buraksenyurt.com/image.axd?picture=/2018/01/ebpython_0_2.gif" alt="" /></p>
<p>Adres satırından da göreceğiniz gibi her şey Amazon'un doğu Amerika bölgesinde bir yerlerde gerçekleşmekteydi(Sanırım) Kuvvetle muhtemel domain'in arkasında o bölgeye ait bir Cloud Server deposu ve EC2 makine örnekleri yer almaktaydı. Yönetim panelini kullanarak bu platform üzerine dosya bırakma yoluyla da taşımalar yapılabiliyordu. Benim merak ettiğim konu ise kendi geliştirme ortamımda yazdığım bir uygulamay<em>ı(veya hazır şablondan üretilmiş bir tanesini)</em> komut satırından Elastic Beanstalk ortamına nasıl aktarabileceğimdi. </p>
<p>O zaman maceramıza başlayalım. Yapacaklarımız özetle oldukça basit. West-world üzerinde(ki artık 64bit çalışan Ubuntu 16.04 sistemi olduğunu biliyorsunuz) sanal bir çalışma ortamı hazırlayacağız. Ardından bu ortamda Django çatısını kullanarak hazır bir web şablonu üreteceğiz. Elastic Beanstalk için gerekli olan çevre değişkenlerini ayarladıktan sonra bir Local Repository üretip taşıma adımlarını işleteceğiz.</p>
<h1>VirtualEnv Gerekli</h1>
<p>VirtualEnv ile linux üzerinde sanal bir ortam hazırlamamız mümkün. Bunu daha çok sistemde var olan paketlerden daha eski veya yeni sürümlerini kullanmak istediğimiz uygulamalarda ele alabiliriz.</p>
<pre class="brush:bash;auto-links:false;toolbar:false" contenteditable="false">sudo apt-get install virtualenv</pre>
<p><img src="https://buraksenyurt.com/image.axd?picture=/2018/01/ebpython_1.gif" alt="" /></p>
<h1>Sanal Ortamın Kurulumu</h1>
<p>VirtualEnv aracı hazır olduğuna göre artık sanal ortamın kurulmasına başlanabilir.</p>
<pre class="brush:bash;auto-links:false;toolbar:false" contenteditable="false">virtualenv ~/beanstalk-virt</pre>
<p>ile python odaklı sanal ortam kurulur. Oluşan klasör içeriğine bakıldığında Python ile hazırlanmış kod dosyaları ve ortam enstrümanları olduğu görülür. Sürüm olarak Python 2.7 söz konusudur ki Amazon Elastic Beanstalk'da bu Python sürümünü tavsiye etmektedir. Sanal ortamı etkinleştirmek içinse aşağıdaki komutu kullanabiliriz.</p>
<pre class="brush:bash;auto-links:false;toolbar:false" contenteditable="false">source ~/beanstalk-virt/bin/activate</pre>
<p><img src="https://buraksenyurt.com/image.axd?picture=/2018/01/ebpython_2.gif" alt="" /></p>
<p>Artık West-World'ün üzerinde tamamen izole bir çalışma sahası var. </p>
<h1>Sahne Django'nun</h1>
<p>Python tarafında web uygulaması geliştirmek için kullanılan en popüler çatılardan birisi Django. Sanal ortama pip paket yöneticisi yardımıyla ilgili çatıyı kurmak gerekiyor.</p>
<pre class="brush:bash;auto-links:false;toolbar:false" contenteditable="false">pip install django==1.9.12</pre>
<p>Amazon dokümantasyonuna göre desteklenen Django versiyonu önemli. Ben araştırmalarımı yaptığım sırada Amazon 1.9.12 sürümünün kullanılması tavsiye ediliyordu.</p>
<p><img src="https://buraksenyurt.com/image.axd?picture=/2018/01/ebpython_3.gif" alt="" /></p>
<p>Kurulum başarılı bir şekilde tamamlandıktan sonra hemen hazır web şablonu kullanılarak bir proje oluşturabiliriz. Aşağıdaki komut bunun için yeterli.</p>
<pre class="brush:bash;auto-links:false;toolbar:false" contenteditable="false">django-admin startproject amznWebStore</pre>
<p>Projenin adı amznWebStore. Klasör içeriğine bakıldığında Python kod dosyalarından oluşan basit bir içerik oluşturulduğu görülebilir. Projeyi bu haliyle local makine üzerinden çalıştırmak istersek manage.py kod dosyasının aşağıdaki gibi çağırılması yeterlidir.</p>
<pre class="brush:bash;auto-links:false;toolbar:false" contenteditable="false">python manage.py runserver</pre>
<p>Eğer işler yolunda gittiyse varsayılan olarak localhost'un 8000 numaralı portu üzerinden web içeriğine ulaşabiliriz.</p>
<p><img src="https://buraksenyurt.com/image.axd?picture=/2018/01/ebpython_4.gif" alt="" /></p>
<h1>Uygulamanın Elastic Beanstalk'a Taşınması</h1>
<p>Buraya kadarki işlemlerimizi şöyle bir hatırlayalım. İlk olarak West-World üzerinde sanal bir ortam açtık. Sanal ortam üzerinde Python yüklü olarak geliyordu. Oluşturulan ortamı etkinleştirdikten sonra basit bir Web uygulamasını ayağa kaldırmak için Django Framework'ü kurduk. Hiçbir kod değişikliği yapmadan manage.py dosyasından yararlanarak bu standart şablonun 127.0.0.1:8000 adresinden ayağa kaldırıldığını gördük. Sırada bu uygulamanın Elastic Beanstalk'a taşınması var. Önce bir kaç hazırlık yapmamız gerekiyor. İlk olarak ortam gereksinimlerin text dosyaya alıyoruz.</p>
<pre class="brush:bash;auto-links:false;toolbar:false" contenteditable="false">pip freeze > requriements.txt</pre>
<p><img src="https://buraksenyurt.com/image.axd?picture=/2018/01/ebpython_5.gif" alt="" /></p>
<p>Dosya içeriğinde aslında tek bir gereksinim var o da taşımanın yapılacağı ortamda Django'nun 1.9.12 sürümünün olmasını istiyor. Takip eden adımda amznWebStore kök dizini altında .ebextensions isimli yeni bir klasör oluşturup içerisine django.config isimli bir dosya atmamız gerekiyor. Bu dosyanın içeriği aşağıdaki gibi.</p>
<pre class="brush:py;auto-links:false;toolbar:false" contenteditable="false">option_settings:
aws:elasticbeanstalk:container:python:
WSGIPath: amznWebStore/wsgi.py</pre>
<p>Aslında Elastic Beanstalk ortamına söz konusu uygulamayı nereden başlatacağını söylemekteyiz ki bu senaryoda wsgi.py dosyası oluyor. Bu son iki adım bize şunu öğretmekte. Sanal ortamda geliştireceğimiz web uygulaması içerisinde neleri kullanırsak<em>(söz gelimi SQLite gibi bir veritabanı, Flesk çatısı vb)</em> bunların Elastic Beanstalk'a söylenmesi gerekmekte.</p>
<p>Sırada Command Languagen Interface'i kullanarak Local Repository'nin oluşturulması adımı var. Tabii bu aşamada benim gibi aşağıda görülen sorunlarla karşılaşabilirsiniz.</p>
<p><img src="https://buraksenyurt.com/image.axd?picture=/2018/01/ebpython_7.gif" alt="" /></p>
<p>İlk olarak eb isimli CLI aracı sisteminizde yüklü olmayabilir. Python ile yazılmış olan bu aracı kullanabilmek için pip yöneticisi ile kurmak gerekiyor. Lakin bu kurulum sanal ortamda gerçekleştirilebilen bir kurulum da değil. Benim düştüğüm bir diğer hata da bu oldu. deactivate komutu ile beanstalk-virt isimli sanal ortamdan çıktıktan sonra gerekli kurulum işlemini yaptım. Sonrasında sanal ortamı etkinleştirip eb init operasyonunu bir kez daha denedim.</p>
<p>Bu sefer daha farklı bir durumla karşılaştım. İlk olarak hangi bölge üzerine taşıma yapmak istediğimi sorduğunu düşündüğüm bir liste ile karşılaştım. Amazon web sitesi üzerinden yaptığım örneği düşünerekten us-east-2<em>(13ncü bölge)</em> seçimini yaptım. Tabii sonrasında gelen hata mesajı gayet açıktı. Credential bilgilerimi bildirmediğim için yetki hatası almıştım. Hemen <a href="https://console.aws.amazon.com/iam/home#/home" target="_blank">Amazon Web Console</a>'a geçerek ve AdministratorAccess Policy'sini kullanan westworld-buraksenyurt isimli bir kullanıcı oluşturdum. Access Key ID ve Secret Access Key değerlerini credential bilgilendirmesi için kullanarak adımı tamamlamayı başardım.</p>
<p><img src="https://buraksenyurt.com/image.axd?picture=/2018/01/ebpython_8.gif" alt="" /></p>
<p>Sonunda uygulama oluşturuldu. Artık tek yapılması gereken ortamın EB üzerine taşınmasıydı. Aşağıdaki komut ile bunu denedim.</p>
<pre class="brush:bash;auto-links:false;toolbar:false" contenteditable="false">eb create my-eb-sample-env</pre>
<p>Evdeki hesap çarşıya uymamış gibiydi.</p>
<p><img src="https://buraksenyurt.com/image.axd?picture=/2018/01/ebpython_9.gif" alt="" /></p>
<p>Üstüne üstelik bir de şu vardı.</p>
<p><img src="https://buraksenyurt.com/image.axd?picture=/2018/01/ebpython_10.gif" alt="" /></p>
<p>Ne yazık ki sonuç pek beklediğim gibi olmadı. Komut satırı hareketliliklerini izlerken Elastic Beanstalk üzerinde my-eb-sample-env isimli uygulamanın oluşturulduğunu gördüm ancak site üzerinden yaptığım uygulama gibi yeşil değil kırmızı renkteydi. Ayrıca komut satırına requriements.txt dosyasının geçersiz olduğuna dair hata mesajı düşmüştü. Requirements.txt dosyasının oluşturulduğu adıma geri dönerek sorunu anlamaya çalıştım. İlk iş içeriğini aşağıdaki hale getirdim.</p>
<pre class="brush:plain;auto-links:false;toolbar:false" contenteditable="false">Django==1.9.12</pre>
<p>Başka bir şeye ihtiyacım yoktu çünkü. Tekrardan </p>
<pre class="brush:bash;auto-links:false;toolbar:false" contenteditable="false">eb deploy</pre>
<p>ile taşıma işlemini yaptım. Şaşılacak şekilde yeşil oku gördüm. Uygulama Elastic Beanstalk üzerinde sağlıklı bir şekilde ayağa kalkmış gibi duruyordu. Komut satırından</p>
<pre class="brush:bash;auto-links:false;toolbar:false" contenteditable="false">eb open</pre>
<p>ile siteyi açtırmak istediğimdeyse yine hüsranla karşılaştım. HTTP_HOST header bilgisinin geçersiz olduğu söyleniyordu.</p>
<p><img src="https://buraksenyurt.com/image.axd?picture=/2018/01/ebpython_11.gif" alt="" /></p>
<p>Bunun üzerine amznWebStore klasöründeki settings.py dosyasını açıp ALLOWED_HOSTS değerinin olduğu satırı bulup aşağıdaki hale getirdim.</p>
<pre class="brush:py;auto-links:false;toolbar:false" contenteditable="false">ALLOWED_HOSTS = ['my-eb-sample-env.prii9kimtp.us-east-2.elasticbeanstalk.com']</pre>
<p>Sonrasında tekrar deploy ve tekrar open.</p>
<pre class="brush:bash;auto-links:false;toolbar:false" contenteditable="false">eb deploy
eb open</pre>
<p>Nihayet! Uygulama Elastic Beanstalk üzerine başarılı bir şekilde taşınmış ve ayağa kaldırılmıştı. </p>
<p><img src="https://buraksenyurt.com/image.axd?picture=/2018/01/ebpython_12.gif" alt="" /></p>
<p>Biraz yorucu bir çalışma olduğunu ifade edebilirim ancak West-World üzerinde kurgulanan senaryonun Amazon Elastic Beanstalk üzerinde konuşlanması tatmin ediciydi de diyebilirim. Bu çalışma bana bir çok şey kattı. Bir PaaS'in tam olarak ne işe yarayabileceğini görme fırsatı buldum. Amazon Console penceresini kullanırken her deployment denemesi sonrası web panelindeki anlık hareketleri inceleyip başarılı bir log sisteminin nasıl olabileceğini ve monitoring'in ne kadar önemli olduğunu anladım. Belki Django ile oluşturulan web uygulaması için hiç kod yazmadım ama taşıma öncesinde platformun hangi gereksinimlere ihtiyacı olduğunun nasıl söylenebileceğini gördüm. Her anlamda yararlı bir çalışma olduğunu ifade edebilirim. Umarım sizler için de bilgilendirici olmuştur. AWS tarafını incelemeye devam ediyorum. Yeni bir şeyler öğrendikçe paylaşmaya çalışacağım. Tekrardan görüşünceye dek hepinize mutlu günler dilerim.</p>2018-02-16T05:00:00+00:00pythonawsamazon web servicescloud computingpaasdjangoiaasamazonamazon elastic cloudamazon ec2bsenyurtBu yazımızda Django çatısından üretilmiş standart bir web uygulamasını, Amazon'un Platform As A Service olarak konumlandırdığı Elastic Beanstalk üzerine nasıl taşıyabileceğimizi öğrenmeye çalışıyoruz. Yolda tabii ki başımıza garip garip olaylar da geliyor. Özellikle sonlara doğru yaşadığımız sıkıntıları çözmeye de çalışıyoruz. Haydi gelin başlayalım.https://buraksenyurt.com/pingback.axdhttps://buraksenyurt.com/post.aspx?id=f1115529-4919-4642-ba2a-1301a6e150d71https://buraksenyurt.com/trackback.axd?id=f1115529-4919-4642-ba2a-1301a6e150d7https://buraksenyurt.com/post/bir-aws-elastic-beanstalk-macerasi#commenthttps://buraksenyurt.com/syndication.axd?post=f1115529-4919-4642-ba2a-1301a6e150d7