āĻšāĻžāĻ āĻ¸āĻŦ. āĻāĻŽāĻ°āĻž āĻ¨āĻŋāĻŦāĻ¨ā§āĻ§ā§āĻ° āĻā§āĻĄāĻŧāĻžāĻ¨ā§āĻ¤ āĻ
āĻāĻļā§āĻ° āĻ
āĻ¨ā§āĻŦāĻžāĻĻ āĻļā§āĻ¯āĻŧāĻžāĻ° āĻāĻ°āĻāĻŋ, āĻ¯āĻž āĻŦāĻŋāĻļā§āĻˇāĻāĻžāĻŦā§ āĻā§āĻ°ā§āĻ¸ā§āĻ° āĻļāĻŋāĻā§āĻˇāĻžāĻ°ā§āĻĨā§āĻĻā§āĻ° āĻāĻ¨ā§āĻ¯ āĻ¤ā§āĻ°āĻŋ āĻāĻ°āĻž āĻšāĻ¯āĻŧā§āĻā§āĨ¤
āĻ°āĻŋāĻ¯āĻŧā§āĻ˛-āĻāĻžāĻāĻŽ āĻĒāĻžāĻāĻĒāĻ˛āĻžāĻāĻ¨ā§āĻ° āĻāĻ¨ā§āĻ¯ Apache Beam āĻāĻŦāĻ DataFlow
Google āĻā§āĻ˛āĻžāĻāĻĄ āĻ¸ā§āĻ āĻāĻĒ āĻāĻ°āĻž āĻšāĻā§āĻā§
āĻĻā§āĻ°āĻˇā§āĻāĻŦā§āĻ¯: āĻāĻŽāĻŋ āĻĒāĻžāĻāĻĒāĻ˛āĻžāĻāĻ¨ āĻāĻžāĻ˛āĻžāĻ¤ā§ āĻāĻŦāĻ āĻāĻžāĻ¸ā§āĻāĻŽ āĻ˛āĻ āĻĄā§āĻāĻž āĻĒā§āĻ°āĻāĻžāĻļ āĻāĻ°āĻ¤ā§ Google āĻā§āĻ˛āĻžāĻāĻĄ āĻļā§āĻ˛ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§āĻāĻŋ āĻāĻžāĻ°āĻŖ āĻĒāĻžāĻāĻĨāĻ¨ 3-āĻ āĻĒāĻžāĻāĻĒāĻ˛āĻžāĻāĻ¨ āĻāĻžāĻ˛āĻžāĻ¤ā§ āĻāĻŽāĻžāĻ° āĻ¸āĻŽāĻ¸ā§āĻ¯āĻž āĻšāĻā§āĻāĻŋāĻ˛ā§ˇ Google āĻā§āĻ˛āĻžāĻāĻĄ āĻļā§āĻ˛ āĻĒāĻžāĻāĻĨāĻ¨ 2 āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§, āĻ¯āĻž Apache Beam-āĻāĻ° āĻ¸āĻžāĻĨā§ āĻāĻ°āĻ āĻ¸āĻžāĻŽāĻā§āĻāĻ¸ā§āĻ¯āĻĒā§āĻ°ā§āĻŖā§ˇ
āĻĒāĻžāĻāĻĒāĻ˛āĻžāĻāĻ¨ āĻļā§āĻ°ā§ āĻāĻ°āĻ¤ā§, āĻāĻŽāĻžāĻĻā§āĻ° āĻ¸ā§āĻāĻŋāĻāĻ¸ā§ āĻāĻāĻā§ āĻāĻ¨āĻ¨ āĻāĻ°āĻ¤ā§ āĻšāĻŦā§āĨ¤ āĻāĻĒāĻ¨āĻžāĻ°āĻž āĻ¯āĻžāĻ°āĻž āĻāĻā§ GCP āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§āĻ¨āĻ¨āĻŋ, āĻ¤āĻžāĻĻā§āĻ° āĻāĻ¨ā§āĻ¯ āĻāĻĒāĻ¨āĻžāĻā§ āĻāĻ¤ā§ āĻāĻ˛ā§āĻ˛ā§āĻāĻŋāĻ¤ āĻ¨āĻŋāĻŽā§āĻ¨āĻ˛āĻŋāĻāĻŋāĻ¤ 6āĻāĻŋ āĻ§āĻžāĻĒ āĻ
āĻ¨ā§āĻ¸āĻ°āĻŖ āĻāĻ°āĻ¤ā§ āĻšāĻŦā§
āĻāĻ° āĻĒāĻ°ā§, āĻāĻŽāĻžāĻĻā§āĻ° Google āĻā§āĻ˛āĻžāĻāĻĄ āĻ¸ā§āĻā§āĻ°ā§āĻā§ āĻāĻŽāĻžāĻĻā§āĻ° āĻ¸ā§āĻā§āĻ°āĻŋāĻĒā§āĻāĻā§āĻ˛āĻŋ āĻāĻĒāĻ˛ā§āĻĄ āĻāĻ°āĻ¤ā§ āĻšāĻŦā§ āĻāĻŦāĻ āĻ¸ā§āĻā§āĻ˛āĻŋāĻā§ āĻāĻŽāĻžāĻĻā§āĻ° Google āĻā§āĻ˛āĻžāĻāĻĄ āĻļā§āĻ˛ā§ āĻ
āĻ¨ā§āĻ˛āĻŋāĻĒāĻŋ āĻāĻ°āĻ¤ā§ āĻšāĻŦā§āĨ¤ āĻā§āĻ˛āĻžāĻāĻĄ āĻ¸ā§āĻā§āĻ°ā§āĻā§ āĻāĻĒāĻ˛ā§āĻĄ āĻāĻ°āĻž āĻŦā§āĻļ āĻ¤ā§āĻā§āĻ (āĻāĻāĻāĻŋ āĻŦāĻ°ā§āĻŖāĻ¨āĻž āĻĒāĻžāĻāĻ¯āĻŧāĻž āĻ¯āĻžāĻŦā§
2 āĻāĻŋāĻ¤ā§āĻ°
āĻĢāĻžāĻāĻ˛āĻā§āĻ˛āĻŋ āĻ āĻ¨ā§āĻ˛āĻŋāĻĒāĻŋ āĻāĻ°āĻ¤ā§ āĻāĻŦāĻ āĻĒā§āĻ°āĻ¯āĻŧā§āĻāĻ¨ā§āĻ¯āĻŧ āĻ˛āĻžāĻāĻŦā§āĻ°ā§āĻ°āĻŋāĻā§āĻ˛āĻŋ āĻāĻ¨āĻ¸ā§āĻāĻ˛ āĻāĻ°āĻžāĻ° āĻāĻ¨ā§āĻ¯ āĻāĻŽāĻžāĻĻā§āĻ° āĻ¯ā§ āĻāĻŽāĻžāĻ¨ā§āĻĄāĻā§āĻ˛āĻŋ āĻĒā§āĻ°āĻ¯āĻŧā§āĻāĻ¨ āĻ¤āĻž āĻ¨ā§āĻā§ āĻ¤āĻžāĻ˛āĻŋāĻāĻžāĻā§āĻā§āĻ¤ āĻāĻ°āĻž āĻšāĻ¯āĻŧā§āĻā§āĨ¤
# Copy file from cloud storage
gsutil cp gs://<YOUR-BUCKET>/ * .
sudo pip install apache-beam[gcp] oauth2client==3.0.0
sudo pip install -U pip
sudo pip install Faker==1.0.2
# Environment variables
BUCKET=<YOUR-BUCKET>
PROJECT=<YOUR-PROJECT>
āĻāĻŽāĻžāĻĻā§āĻ° āĻĄāĻžāĻāĻžāĻŦā§āĻ¸ āĻāĻŦāĻ āĻā§āĻŦāĻŋāĻ˛ āĻ¤ā§āĻ°āĻŋ āĻāĻ°āĻž āĻšāĻā§āĻā§
āĻāĻāĻŦāĻžāĻ° āĻāĻŽāĻ°āĻž āĻ¸ā§āĻāĻāĻĒ āĻ¸āĻŽā§āĻĒāĻ°ā§āĻāĻŋāĻ¤ āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻĒāĻĻāĻā§āĻˇā§āĻĒāĻā§āĻ˛āĻŋ āĻ¸āĻŽā§āĻĒāĻ¨ā§āĻ¨ āĻāĻ°āĻžāĻ° āĻĒāĻ°ā§, āĻāĻŽāĻžāĻĻā§āĻ° āĻĒāĻ°āĻŦāĻ°ā§āĻ¤ā§ āĻāĻŋāĻ¨āĻŋāĻ¸āĻāĻŋ BigQuery-āĻ āĻāĻāĻāĻŋ āĻĄā§āĻāĻžāĻ¸ā§āĻ āĻāĻŦāĻ āĻā§āĻŦāĻŋāĻ˛ āĻ¤ā§āĻ°āĻŋ āĻāĻ°āĻ¤ā§ āĻšāĻŦā§ā§ˇ āĻāĻāĻŋ āĻāĻ°āĻžāĻ° āĻŦāĻŋāĻāĻŋāĻ¨ā§āĻ¨ āĻāĻĒāĻžāĻ¯āĻŧ āĻ°āĻ¯āĻŧā§āĻā§, āĻ¤āĻŦā§ āĻ¸āĻŦāĻā§āĻ¯āĻŧā§ āĻ¸āĻšāĻ āĻšāĻ˛ āĻĒā§āĻ°āĻĨāĻŽā§ āĻāĻāĻāĻŋ āĻĄā§āĻāĻžāĻ¸ā§āĻ āĻ¤ā§āĻ°āĻŋ āĻāĻ°ā§ Google āĻā§āĻ˛āĻžāĻāĻĄ āĻāĻ¨āĻ¸ā§āĻ˛ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°āĻžā§ˇ āĻāĻĒāĻ¨āĻŋ āĻ¨ā§āĻā§āĻ° āĻĒāĻĻāĻā§āĻˇā§āĻĒāĻā§āĻ˛āĻŋ āĻ
āĻ¨ā§āĻ¸āĻ°āĻŖ āĻāĻ°āĻ¤ā§ āĻĒāĻžāĻ°ā§āĻ¨
āĻāĻŋāĻ¤ā§āĻ° 3. āĻā§āĻŦāĻŋāĻ˛ āĻ˛ā§āĻāĻāĻ
āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ°āĻāĻžāĻ°ā§āĻ° āĻ˛āĻ āĻĄā§āĻāĻž āĻĒā§āĻ°āĻāĻžāĻļ āĻāĻ°āĻž āĻšāĻā§āĻā§
āĻĒāĻžāĻŦ/āĻ¸āĻžāĻŦ āĻāĻŽāĻžāĻĻā§āĻ° āĻĒāĻžāĻāĻĒāĻ˛āĻžāĻāĻ¨ā§āĻ° āĻāĻāĻāĻŋ āĻā§āĻ°ā§āĻ¤ā§āĻŦāĻĒā§āĻ°ā§āĻŖ āĻāĻĒāĻžāĻĻāĻžāĻ¨ āĻāĻžāĻ°āĻŖ āĻāĻāĻŋ āĻāĻāĻžāĻ§āĻŋāĻ āĻ¸ā§āĻŦāĻžāĻ§ā§āĻ¨ āĻ ā§āĻ¯āĻžāĻĒā§āĻ˛āĻŋāĻā§āĻļāĻ¨āĻā§ āĻāĻā§ āĻ āĻĒāĻ°ā§āĻ° āĻ¸āĻžāĻĨā§ āĻ¯ā§āĻāĻžāĻ¯ā§āĻ āĻāĻ°āĻ¤ā§ āĻĻā§āĻ¯āĻŧāĨ¤ āĻŦāĻŋāĻļā§āĻˇāĻ¤, āĻāĻāĻŋ āĻāĻāĻāĻŋ āĻŽāĻ§ā§āĻ¯āĻ¸ā§āĻĨāĻ¤āĻžāĻāĻžāĻ°ā§ āĻšāĻŋāĻ¸āĻžāĻŦā§ āĻāĻžāĻ āĻāĻ°ā§ āĻ¯āĻž āĻāĻŽāĻžāĻĻā§āĻ° āĻ ā§āĻ¯āĻžāĻĒā§āĻ˛āĻŋāĻā§āĻļāĻ¨āĻā§āĻ˛āĻŋāĻ° āĻŽāĻ§ā§āĻ¯ā§ āĻŦāĻžāĻ°ā§āĻ¤āĻž āĻĒāĻžāĻ āĻžāĻ¤ā§ āĻāĻŦāĻ āĻā§āĻ°āĻšāĻŖ āĻāĻ°āĻ¤ā§ āĻĻā§āĻ¯āĻŧā§ˇ āĻāĻŽāĻžāĻĻā§āĻ° āĻĒā§āĻ°āĻĨāĻŽā§ āĻāĻāĻāĻŋ āĻŦāĻŋāĻˇāĻ¯āĻŧ āĻ¤ā§āĻ°āĻŋ āĻāĻ°āĻ¤ā§ āĻšāĻŦā§āĨ¤ āĻāĻ¨āĻ¸ā§āĻ˛ā§ āĻļā§āĻ§ā§ āĻĒāĻžāĻŦ/āĻ¸āĻžāĻŦ-āĻ āĻ¯āĻžāĻ¨ āĻāĻŦāĻ āĻāĻĒāĻŋāĻ āĻ¤ā§āĻ°āĻŋ āĻāĻ°ā§āĻ¨ āĻā§āĻ˛āĻŋāĻ āĻāĻ°ā§āĻ¨āĨ¤
āĻ¨ā§āĻā§āĻ° āĻā§āĻĄāĻāĻŋ āĻāĻĒāĻ°ā§ āĻ¸āĻāĻā§āĻāĻžāĻ¯āĻŧāĻŋāĻ¤ āĻ˛āĻ āĻĄā§āĻāĻž āĻ¤ā§āĻ°āĻŋ āĻāĻ°āĻ¤ā§ āĻāĻŽāĻžāĻĻā§āĻ° āĻ¸ā§āĻā§āĻ°āĻŋāĻĒā§āĻāĻā§ āĻāĻ˛ āĻāĻ°ā§ āĻāĻŦāĻ āĻ¤āĻžāĻ°āĻĒāĻ° āĻ˛āĻāĻā§āĻ˛āĻŋāĻā§ Pub/Sub-āĻ āĻ¸āĻāĻ¯ā§āĻā§āĻ¤ āĻāĻ°ā§ āĻĒāĻžāĻ āĻžāĻ¯āĻŧāĨ¤ āĻāĻŽāĻžāĻĻā§āĻ° āĻ¯āĻž āĻāĻ°āĻ¤ā§ āĻšāĻŦā§ āĻ¤āĻž āĻšāĻ˛ āĻāĻāĻāĻŋ āĻŦāĻ¸ā§āĻ¤ā§ āĻ¤ā§āĻ°āĻŋ āĻāĻ°āĻž āĻĒā§āĻ°āĻāĻžāĻļāĻ āĻā§āĻ˛āĻžāĻ¯āĻŧā§āĻ¨ā§āĻ, āĻĒāĻĻā§āĻ§āĻ¤āĻŋ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§ āĻŦāĻŋāĻˇāĻ¯āĻŧā§āĻ° āĻĒāĻĨ āĻ¨āĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āĻ āĻāĻ°ā§āĻ¨ topic_path
āĻāĻŦāĻ āĻĢāĻžāĻāĻļāĻ¨ āĻāĻ˛ āĻāĻ°ā§āĻ¨ publish
Ņ topic_path
āĻāĻŦāĻ āĻĄā§āĻāĻžāĨ¤ āĻĻāĻ¯āĻŧāĻž āĻāĻ°ā§ āĻ¨ā§āĻ āĻāĻ°ā§āĻ¨ āĻ¯ā§ āĻāĻŽāĻ°āĻž āĻāĻŽāĻĻāĻžāĻ¨āĻŋ āĻāĻ°āĻŋ generate_log_line
āĻāĻŽāĻžāĻĻā§āĻ° āĻ¸ā§āĻā§āĻ°āĻŋāĻĒā§āĻ āĻĨā§āĻā§ stream_logs
, āĻ¤āĻžāĻ āĻ¨āĻŋāĻļā§āĻāĻŋāĻ¤ āĻāĻ°ā§āĻ¨ āĻ¯ā§ āĻāĻ āĻĢāĻžāĻāĻ˛āĻā§āĻ˛āĻŋ āĻāĻāĻ āĻĢā§āĻ˛ā§āĻĄāĻžāĻ°ā§ āĻāĻā§, āĻ
āĻ¨ā§āĻ¯āĻĨāĻžāĻ¯āĻŧ āĻāĻĒāĻ¨āĻŋ āĻāĻāĻāĻŋ āĻāĻŽāĻĻāĻžāĻ¨āĻŋ āĻ¤ā§āĻ°ā§āĻāĻŋ āĻĒāĻžāĻŦā§āĻ¨āĨ¤ āĻ¤āĻžāĻ°āĻĒāĻ°ā§ āĻāĻŽāĻ°āĻž āĻāĻāĻŋ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§ āĻāĻŽāĻžāĻĻā§āĻ° āĻā§āĻāĻ˛ āĻāĻ¨āĻ¸ā§āĻ˛ā§āĻ° āĻŽāĻžāĻ§ā§āĻ¯āĻŽā§ āĻāĻāĻŋ āĻāĻžāĻ˛āĻžāĻ¤ā§ āĻĒāĻžāĻ°āĻŋ:
python publish.py
from stream_logs import generate_log_line
import logging
from google.cloud import pubsub_v1
import random
import time
PROJECT_ID="user-logs-237110"
TOPIC = "userlogs"
publisher = pubsub_v1.PublisherClient()
topic_path = publisher.topic_path(PROJECT_ID, TOPIC)
def publish(publisher, topic, message):
data = message.encode('utf-8')
return publisher.publish(topic_path, data = data)
def callback(message_future):
# When timeout is unspecified, the exception method waits indefinitely.
if message_future.exception(timeout=30):
print('Publishing message on {} threw an Exception {}.'.format(
topic_name, message_future.exception()))
else:
print(message_future.result())
if __name__ == '__main__':
while True:
line = generate_log_line()
print(line)
message_future = publish(publisher, topic_path, line)
message_future.add_done_callback(callback)
sleep_time = random.choice(range(1, 3, 1))
time.sleep(sleep_time)
āĻĢāĻžāĻāĻ˛āĻāĻŋ āĻāĻžāĻ˛āĻžāĻ¨ā§āĻ° āĻ¸āĻžāĻĨā§ āĻ¸āĻžāĻĨā§, āĻāĻŽāĻ°āĻž āĻāĻ¨āĻ¸ā§āĻ˛ā§ āĻ˛āĻ āĻĄā§āĻāĻžāĻ° āĻāĻāĻāĻĒā§āĻ āĻĻā§āĻāĻ¤ā§ āĻ¸āĻā§āĻˇāĻŽ āĻšāĻŦ, āĻ¯ā§āĻŽāĻ¨āĻāĻŋ āĻ¨ā§āĻā§āĻ° āĻāĻŋāĻ¤ā§āĻ°ā§ āĻĻā§āĻāĻžāĻ¨ā§ āĻšāĻ¯āĻŧā§āĻā§āĨ¤ āĻāĻ āĻ¸ā§āĻā§āĻ°āĻŋāĻĒā§āĻāĻāĻŋ āĻāĻžāĻ āĻāĻ°āĻŦā§ āĻ¯āĻ¤āĻā§āĻˇāĻŖ āĻ¨āĻž āĻāĻŽāĻ°āĻž āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°āĻŋ āĻāĻŦāĻžāĻ° CTRL + āĻ¸āĻŋāĻāĻāĻž āĻ¸āĻŽā§āĻĒā§āĻ°ā§āĻŖ āĻāĻ°āĻ¤ā§
āĻāĻŋāĻ¤ā§āĻ° 4. āĻāĻāĻāĻĒā§āĻ publish_logs.py
āĻāĻŽāĻžāĻĻā§āĻ° āĻĒāĻžāĻāĻĒāĻ˛āĻžāĻāĻ¨ āĻā§āĻĄ āĻ˛ā§āĻāĻž
āĻāĻāĻ¨ āĻ¯ā§āĻšā§āĻ¤ā§ āĻāĻŽāĻ°āĻž āĻ¸āĻŦāĻāĻŋāĻā§ āĻĒā§āĻ°āĻ¸ā§āĻ¤ā§āĻ¤ āĻāĻ°ā§āĻāĻŋ, āĻāĻŽāĻ°āĻž āĻŽāĻāĻžāĻ° āĻ
āĻāĻļ āĻļā§āĻ°ā§ āĻāĻ°āĻ¤ā§ āĻĒāĻžāĻ°āĻŋ - āĻŦāĻŋāĻŽ āĻāĻŦāĻ āĻĒāĻžāĻāĻĨāĻ¨ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§ āĻāĻŽāĻžāĻĻā§āĻ° āĻĒāĻžāĻāĻĒāĻ˛āĻžāĻāĻ¨ āĻā§āĻĄāĻŋāĻ āĻāĻ°āĻžāĨ¤ āĻāĻāĻāĻŋ āĻŦāĻŋāĻŽ āĻĒāĻžāĻāĻĒāĻ˛āĻžāĻāĻ¨ āĻ¤ā§āĻ°āĻŋ āĻāĻ°āĻ¤ā§, āĻāĻŽāĻžāĻĻā§āĻ° āĻāĻāĻāĻŋ āĻĒāĻžāĻāĻĒāĻ˛āĻžāĻāĻ¨ āĻ
āĻŦāĻā§āĻā§āĻ (āĻĒāĻŋ) āĻ¤ā§āĻ°āĻŋ āĻāĻ°āĻ¤ā§ āĻšāĻŦā§āĨ¤ āĻāĻāĻŦāĻžāĻ° āĻāĻŽāĻ°āĻž āĻāĻāĻāĻŋ āĻĒāĻžāĻāĻĒāĻ˛āĻžāĻāĻ¨ āĻ
āĻŦāĻā§āĻā§āĻ āĻ¤ā§āĻ°āĻŋ āĻāĻ°āĻ˛ā§, āĻāĻŽāĻ°āĻž āĻ
āĻĒāĻžāĻ°ā§āĻāĻ° āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§ āĻāĻā§āĻ° āĻĒāĻ° āĻāĻ āĻāĻāĻžāĻ§āĻŋāĻ āĻĢāĻžāĻāĻļāĻ¨ āĻĒā§āĻ°āĻ¯āĻŧā§āĻ āĻāĻ°āĻ¤ā§ āĻĒāĻžāĻ°āĻŋ pipe (|)
. āĻ¸āĻžāĻ§āĻžāĻ°āĻŖāĻāĻžāĻŦā§, āĻāĻ°ā§āĻŽāĻĒā§āĻ°āĻŦāĻžāĻšāĻāĻŋ āĻ¨ā§āĻā§āĻ° āĻāĻŋāĻ¤ā§āĻ°ā§āĻ° āĻŽāĻ¤ā§ āĻĻā§āĻāĻžāĻ¯āĻŧāĨ¤
[Final Output PCollection] = ([Initial Input PCollection] | [First Transform]
| [Second Transform]
| [Third Transform])
āĻāĻŽāĻžāĻĻā§āĻ° āĻā§āĻĄā§, āĻāĻŽāĻ°āĻž āĻĻā§āĻāĻŋ āĻāĻžāĻ¸ā§āĻāĻŽ āĻĢāĻžāĻāĻļāĻ¨ āĻ¤ā§āĻ°āĻŋ āĻāĻ°āĻŦāĨ¤ āĻĢāĻžāĻāĻļāĻ¨ regex_clean
, āĻ¯āĻž āĻĄā§āĻāĻž āĻ¸ā§āĻā§āĻ¯āĻžāĻ¨ āĻāĻ°ā§ āĻāĻŦāĻ āĻĢāĻžāĻāĻļāĻ¨ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§ PATTERNS āĻ¤āĻžāĻ˛āĻŋāĻāĻžāĻ° āĻāĻĒāĻ° āĻāĻŋāĻ¤ā§āĻ¤āĻŋ āĻāĻ°ā§ āĻ¸āĻāĻļā§āĻ˛āĻŋāĻˇā§āĻ āĻ¸āĻžāĻ°āĻŋ āĻĒā§āĻ¨āĻ°ā§āĻĻā§āĻ§āĻžāĻ° āĻāĻ°ā§ re.search
. āĻĢāĻžāĻāĻļāĻ¨āĻāĻŋ āĻāĻāĻāĻŋ āĻāĻŽāĻž āĻŦāĻŋāĻāĻā§āĻ¤ āĻ¸ā§āĻā§āĻ°āĻŋāĻ āĻĒā§āĻ°āĻĻāĻžāĻ¨ āĻāĻ°ā§āĨ¤ āĻāĻĒāĻ¨āĻŋ āĻ¯āĻĻāĻŋ āĻ¨āĻŋāĻ¯āĻŧāĻŽāĻŋāĻ¤ āĻāĻā§āĻ¸āĻĒā§āĻ°ā§āĻļāĻ¨ āĻŦāĻŋāĻļā§āĻˇāĻā§āĻ āĻ¨āĻž āĻšāĻ¨ āĻ¤āĻŦā§ āĻāĻŽāĻŋ āĻāĻāĻŋ āĻĒāĻ°ā§āĻā§āĻˇāĻž āĻāĻ°āĻžāĻ° āĻĒāĻ°āĻžāĻŽāĻ°ā§āĻļ āĻĻāĻŋāĻ datetime
āĻāĻāĻŋ āĻāĻžāĻ āĻāĻ°āĻ¤ā§ āĻāĻāĻāĻŋ āĻĢāĻžāĻāĻļāĻ¨ āĻāĻŋāĻ¤āĻ°ā§. āĻāĻŽāĻŋ āĻĢāĻžāĻāĻ˛ā§āĻ° āĻļā§āĻ°ā§āĻ¤ā§ āĻāĻāĻāĻŋ āĻāĻŽāĻĻāĻžāĻ¨āĻŋ āĻ¤ā§āĻ°ā§āĻāĻŋ āĻĒā§āĻ¯āĻŧā§āĻāĻŋāĻ˛āĻžāĻŽ, āĻ¯āĻž āĻ
āĻĻā§āĻā§āĻ¤ āĻāĻŋāĻ˛āĨ¤ āĻāĻ āĻ¤āĻžāĻ˛āĻŋāĻāĻž āĻ¤āĻžāĻ°āĻĒāĻ° āĻĢāĻžāĻāĻļāĻ¨ āĻĒāĻžāĻ¸ āĻāĻ°āĻž āĻšāĻ¯āĻŧ āĻ˛āĻŋāĻā§āĻ¨ToBigQuery, āĻ¯āĻž āĻ¸āĻšāĻāĻāĻžāĻŦā§ āĻā§āĻŦāĻŋāĻ˛ā§ āĻāĻŽāĻžāĻĻā§āĻ° āĻĄā§āĻāĻž āĻ¯ā§āĻ āĻāĻ°ā§āĨ¤ āĻŦā§āĻ¯āĻžāĻ āĻĄā§āĻāĻžāĻĢā§āĻ˛ā§ āĻāĻŦ āĻāĻŦāĻ āĻ¸ā§āĻā§āĻ°āĻŋāĻŽāĻŋāĻ āĻĄā§āĻāĻžāĻĢā§āĻ˛ā§ āĻāĻžāĻā§āĻ° āĻā§āĻĄ āĻ¨ā§āĻā§ āĻĻā§āĻāĻ¯āĻŧāĻž āĻšāĻ˛āĨ¤ āĻŦā§āĻ¯āĻžāĻ āĻāĻŦāĻ āĻ¸ā§āĻā§āĻ°āĻŋāĻŽāĻŋāĻ āĻā§āĻĄā§āĻ° āĻŽāĻ§ā§āĻ¯ā§ āĻāĻāĻŽāĻžāĻ¤ā§āĻ° āĻĒāĻžāĻ°ā§āĻĨāĻā§āĻ¯ āĻšāĻ˛ āĻ¯ā§ āĻŦā§āĻ¯āĻžāĻ āĻĨā§āĻā§ āĻāĻŽāĻ°āĻž CSV āĻĒāĻĄāĻŧāĻŋ src_path
āĻĢāĻžāĻāĻļāĻ¨ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§ ReadFromText
āĻŽāĻ°ā§āĻāĻŋ āĻĨā§āĻā§āĨ¤
āĻŦā§āĻ¯āĻžāĻ āĻĄā§āĻāĻžāĻĢā§āĻ˛ā§ āĻāĻŦ (āĻŦā§āĻ¯āĻžāĻ āĻĒā§āĻ°āĻ¸ā§āĻ¸āĻŋāĻ)
import apache_beam as beam
from apache_beam.options.pipeline_options import PipelineOptions
from google.cloud import bigquery
import re
import logging
import sys
PROJECT='user-logs-237110'
schema = 'remote_addr:STRING, timelocal:STRING, request_type:STRING, status:STRING, body_bytes_sent:STRING, http_referer:STRING, http_user_agent:STRING'
src_path = "user_log_fileC.txt"
def regex_clean(data):
PATTERNS = [r'(^S+.[S+.]+S+)s',r'(?<=[).+?(?=])',
r'"(S+)s(S+)s*(S*)"',r's(d+)s',r"(?<=[).d+(?=])",
r'"[A-Z][a-z]+', r'"(http|https)://[a-z]+.[a-z]+.[a-z]+']
result = []
for match in PATTERNS:
try:
reg_match = re.search(match, data).group()
if reg_match:
result.append(reg_match)
else:
result.append(" ")
except:
print("There was an error with the regex search")
result = [x.strip() for x in result]
result = [x.replace('"', "") for x in result]
res = ','.join(result)
return res
class Split(beam.DoFn):
def process(self, element):
from datetime import datetime
element = element.split(",")
d = datetime.strptime(element[1], "%d/%b/%Y:%H:%M:%S")
date_string = d.strftime("%Y-%m-%d %H:%M:%S")
return [{
'remote_addr': element[0],
'timelocal': date_string,
'request_type': element[2],
'status': element[3],
'body_bytes_sent': element[4],
'http_referer': element[5],
'http_user_agent': element[6]
}]
def main():
p = beam.Pipeline(options=PipelineOptions())
(p
| 'ReadData' >> beam.io.textio.ReadFromText(src_path)
| "clean address" >> beam.Map(regex_clean)
| 'ParseCSV' >> beam.ParDo(Split())
| 'WriteToBigQuery' >> beam.io.WriteToBigQuery('{0}:userlogs.logdata'.format(PROJECT), schema=schema,
write_disposition=beam.io.BigQueryDisposition.WRITE_APPEND)
)
p.run()
if __name__ == '__main__':
logger = logging.getLogger().setLevel(logging.INFO)
main()
āĻ¸ā§āĻā§āĻ°āĻŋāĻŽāĻŋāĻ āĻĄā§āĻāĻžāĻĢā§āĻ˛ā§ āĻāĻŦ (āĻ¸ā§āĻā§āĻ°āĻŋāĻŽ āĻĒā§āĻ°āĻ¸ā§āĻ¸āĻŋāĻ)
from apache_beam.options.pipeline_options import PipelineOptions
from google.cloud import pubsub_v1
from google.cloud import bigquery
import apache_beam as beam
import logging
import argparse
import sys
import re
PROJECT="user-logs-237110"
schema = 'remote_addr:STRING, timelocal:STRING, request_type:STRING, status:STRING, body_bytes_sent:STRING, http_referer:STRING, http_user_agent:STRING'
TOPIC = "projects/user-logs-237110/topics/userlogs"
def regex_clean(data):
PATTERNS = [r'(^S+.[S+.]+S+)s',r'(?<=[).+?(?=])',
r'"(S+)s(S+)s*(S*)"',r's(d+)s',r"(?<=[).d+(?=])",
r'"[A-Z][a-z]+', r'"(http|https)://[a-z]+.[a-z]+.[a-z]+']
result = []
for match in PATTERNS:
try:
reg_match = re.search(match, data).group()
if reg_match:
result.append(reg_match)
else:
result.append(" ")
except:
print("There was an error with the regex search")
result = [x.strip() for x in result]
result = [x.replace('"', "") for x in result]
res = ','.join(result)
return res
class Split(beam.DoFn):
def process(self, element):
from datetime import datetime
element = element.split(",")
d = datetime.strptime(element[1], "%d/%b/%Y:%H:%M:%S")
date_string = d.strftime("%Y-%m-%d %H:%M:%S")
return [{
'remote_addr': element[0],
'timelocal': date_string,
'request_type': element[2],
'body_bytes_sent': element[3],
'status': element[4],
'http_referer': element[5],
'http_user_agent': element[6]
}]
def main(argv=None):
parser = argparse.ArgumentParser()
parser.add_argument("--input_topic")
parser.add_argument("--output")
known_args = parser.parse_known_args(argv)
p = beam.Pipeline(options=PipelineOptions())
(p
| 'ReadData' >> beam.io.ReadFromPubSub(topic=TOPIC).with_output_types(bytes)
| "Decode" >> beam.Map(lambda x: x.decode('utf-8'))
| "Clean Data" >> beam.Map(regex_clean)
| 'ParseCSV' >> beam.ParDo(Split())
| 'WriteToBigQuery' >> beam.io.WriteToBigQuery('{0}:userlogs.logdata'.format(PROJECT), schema=schema,
write_disposition=beam.io.BigQueryDisposition.WRITE_APPEND)
)
result = p.run()
result.wait_until_finish()
if __name__ == '__main__':
logger = logging.getLogger().setLevel(logging.INFO)
main()
āĻĒāĻžāĻāĻĒāĻ˛āĻžāĻāĻ¨ āĻāĻžāĻ˛āĻžāĻā§āĻā§
āĻāĻŽāĻ°āĻž āĻŦāĻŋāĻāĻŋāĻ¨ā§āĻ¨ āĻāĻĒāĻžāĻ¯āĻŧā§ āĻĒāĻžāĻāĻĒāĻ˛āĻžāĻāĻ¨ āĻāĻžāĻ˛āĻžāĻ¤ā§ āĻĒāĻžāĻ°āĻŋāĨ¤ āĻāĻŽāĻ°āĻž āĻāĻžāĻāĻ˛ā§, āĻĻā§āĻ°āĻŦāĻ°ā§āĻ¤ā§āĻāĻžāĻŦā§ GCP-āĻ āĻ˛āĻāĻāĻ¨ āĻāĻ°āĻžāĻ° āĻ¸āĻŽāĻ¯āĻŧ āĻāĻŽāĻ°āĻž āĻāĻāĻŋāĻā§ āĻ¸ā§āĻĨāĻžāĻ¨ā§āĻ¯āĻŧāĻāĻžāĻŦā§ āĻāĻžāĻ°ā§āĻŽāĻŋāĻ¨āĻžāĻ˛ āĻĨā§āĻā§ āĻāĻžāĻ˛āĻžāĻ¤ā§ āĻĒāĻžāĻ°āĻŋāĨ¤
python -m main_pipeline_stream.py
--input_topic "projects/user-logs-237110/topics/userlogs"
--streaming
āĻ¯āĻžāĻāĻšā§āĻ, āĻāĻŽāĻ°āĻž DataFlow āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§ āĻāĻāĻŋ āĻāĻžāĻ˛āĻžāĻ¤ā§ āĻ¯āĻžāĻā§āĻāĻŋāĨ¤ āĻāĻŽāĻ°āĻž āĻ¨āĻŋāĻŽā§āĻ¨āĻ˛āĻŋāĻāĻŋāĻ¤ āĻĒā§āĻ°āĻ¯āĻŧā§āĻāĻ¨ā§āĻ¯āĻŧ āĻĒā§āĻ¯āĻžāĻ°āĻžāĻŽāĻŋāĻāĻžāĻ° āĻ¸ā§āĻ āĻāĻ°ā§ āĻ¨ā§āĻā§āĻ° āĻāĻŽāĻžāĻ¨ā§āĻĄ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§ āĻāĻāĻŋ āĻāĻ°āĻ¤ā§ āĻĒāĻžāĻ°āĻŋāĨ¤
project
â āĻāĻĒāĻ¨āĻžāĻ° GCP āĻĒā§āĻ°āĻāĻ˛ā§āĻĒā§āĻ° āĻāĻāĻĄāĻŋāĨ¤runner
āĻāĻāĻāĻŋ āĻĒāĻžāĻāĻĒāĻ˛āĻžāĻāĻ¨ āĻ°āĻžāĻ¨āĻžāĻ° āĻ¯āĻž āĻāĻĒāĻ¨āĻžāĻ° āĻĒā§āĻ°ā§āĻā§āĻ°āĻžāĻŽ āĻŦāĻŋāĻļā§āĻ˛ā§āĻˇāĻŖ āĻāĻ°āĻŦā§ āĻāĻŦāĻ āĻāĻĒāĻ¨āĻžāĻ° āĻĒāĻžāĻāĻĒāĻ˛āĻžāĻāĻ¨ āĻ¨āĻŋāĻ°ā§āĻŽāĻžāĻŖ āĻāĻ°āĻŦā§āĨ¤ āĻā§āĻ˛āĻžāĻāĻĄā§ āĻāĻžāĻ˛āĻžāĻ¨ā§āĻ° āĻāĻ¨ā§āĻ¯, āĻāĻĒāĻ¨āĻžāĻā§ āĻ āĻŦāĻļā§āĻ¯āĻ āĻāĻāĻāĻŋ DataflowRunner āĻ¨āĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āĻ āĻāĻ°āĻ¤ā§ āĻšāĻŦā§āĨ¤staging_location
â āĻā§āĻ˛āĻžāĻāĻĄ āĻĄā§āĻāĻžāĻĢā§āĻ˛ā§ āĻā§āĻ˛āĻžāĻāĻĄ āĻ¸ā§āĻā§āĻ°ā§āĻā§āĻ° āĻĒāĻžāĻĨ āĻāĻ¨āĻĄā§āĻā§āĻ¸āĻŋāĻ āĻā§āĻĄ āĻĒā§āĻ¯āĻžāĻā§āĻāĻā§āĻ˛āĻŋāĻ° āĻāĻ¨ā§āĻ¯ āĻĒā§āĻ°āĻ¯āĻŧā§āĻāĻ¨ā§āĻ¯āĻŧ āĻĒā§āĻ°āĻ¸ā§āĻ¸āĻ°āĻ°āĻž āĻāĻžāĻ āĻ¸āĻŽā§āĻĒāĻžāĻĻāĻ¨ āĻāĻ°ā§āĨ¤temp_location
â āĻĒāĻžāĻāĻĒāĻ˛āĻžāĻāĻ¨ āĻāĻ˛āĻžāĻāĻžāĻ˛ā§āĻ¨ āĻ¤ā§āĻ°āĻŋ āĻāĻ°āĻž āĻ āĻ¸ā§āĻĨāĻžāĻ¯āĻŧā§ āĻāĻžāĻā§āĻ° āĻĢāĻžāĻāĻ˛ āĻ¸āĻāĻ°āĻā§āĻˇāĻŖā§āĻ° āĻāĻ¨ā§āĻ¯ āĻā§āĻ˛āĻžāĻāĻĄ āĻĄā§āĻāĻžāĻĢā§āĻ˛ā§ āĻā§āĻ˛āĻžāĻāĻĄ āĻ¸ā§āĻā§āĻ°ā§āĻā§āĻ° āĻĒāĻĨāĨ¤streaming
python main_pipeline_stream.py
--runner DataFlow
--project $PROJECT
--temp_location $BUCKET/tmp
--staging_location $BUCKET/staging
--streaming
āĻāĻ āĻāĻŽāĻžāĻ¨ā§āĻĄāĻāĻŋ āĻāĻ˛āĻžāĻāĻžāĻ˛ā§āĻ¨, āĻāĻŽāĻ°āĻž āĻā§āĻāĻ˛ āĻāĻ¨āĻ¸ā§āĻ˛ā§ āĻĄā§āĻāĻžāĻĢā§āĻ˛ā§ āĻā§āĻ¯āĻžāĻŦā§ āĻ¯ā§āĻ¤ā§ āĻĒāĻžāĻ°āĻŋ āĻāĻŦāĻ āĻāĻŽāĻžāĻĻā§āĻ° āĻĒāĻžāĻāĻĒāĻ˛āĻžāĻāĻ¨ āĻĻā§āĻāĻ¤ā§ āĻĒāĻžāĻ°āĻŋāĨ¤ āĻ¯āĻāĻ¨ āĻāĻŽāĻ°āĻž āĻĒāĻžāĻāĻĒāĻ˛āĻžāĻāĻ¨ā§ āĻā§āĻ˛āĻŋāĻ āĻāĻ°āĻŋ, āĻ¤āĻāĻ¨ āĻāĻŽāĻžāĻĻā§āĻ° āĻāĻŋāĻ¤ā§āĻ° 4-āĻāĻ° āĻŽāĻ¤ā§ āĻāĻŋāĻā§ āĻĻā§āĻāĻ¤ā§ āĻĒāĻžāĻāĻ¯āĻŧāĻž āĻāĻāĻŋāĻ¤āĨ¤ āĻĄāĻŋāĻŦāĻžāĻāĻŋāĻāĻ¯āĻŧā§āĻ° āĻāĻĻā§āĻĻā§āĻļā§āĻ¯ā§, āĻŦāĻŋāĻļāĻĻ āĻ˛āĻāĻā§āĻ˛āĻŋ āĻĻā§āĻāĻ¤ā§ āĻ˛āĻ āĻāĻŦāĻ āĻ¤āĻžāĻ°āĻĒāĻ° āĻ¸ā§āĻā§āĻ¯āĻžāĻāĻĄā§āĻ°āĻžāĻāĻāĻžāĻ°ā§ āĻ¯āĻžāĻāĻ¯āĻŧāĻž āĻā§āĻŦ āĻ¸āĻšāĻžāĻ¯āĻŧāĻ āĻšāĻ¤ā§ āĻĒāĻžāĻ°ā§āĨ¤ āĻāĻāĻŋ āĻāĻŽāĻžāĻā§ āĻŦā§āĻļ āĻāĻ¯āĻŧā§āĻāĻāĻŋ āĻā§āĻˇā§āĻ¤ā§āĻ°ā§ āĻĒāĻžāĻāĻĒāĻ˛āĻžāĻāĻ¨ā§āĻ° āĻ¸āĻŽāĻ¸ā§āĻ¯āĻž āĻ¸āĻŽāĻžāĻ§āĻžāĻ¨ āĻāĻ°āĻ¤ā§ āĻ¸āĻžāĻšāĻžāĻ¯ā§āĻ¯ āĻāĻ°ā§āĻā§āĨ¤
āĻāĻŋāĻ¤ā§āĻ° 4: āĻŽāĻ°ā§āĻāĻŋ āĻĒāĻ°āĻŋāĻŦāĻžāĻšāĻ
BigQuery-āĻ āĻāĻŽāĻžāĻĻā§āĻ° āĻĄā§āĻāĻž āĻ ā§āĻ¯āĻžāĻā§āĻ¸ā§āĻ¸ āĻāĻ°ā§āĻ¨
āĻ¸ā§āĻ¤āĻ°āĻžāĻ, āĻāĻŽāĻžāĻĻā§āĻ° āĻāĻ¤āĻŋāĻŽāĻ§ā§āĻ¯ā§āĻ āĻāĻāĻāĻŋ āĻĒāĻžāĻāĻĒāĻ˛āĻžāĻāĻ¨ āĻĨāĻžāĻāĻž āĻāĻāĻŋāĻ¤ āĻ¯āĻžāĻ¤ā§ āĻĄā§āĻāĻž āĻāĻŽāĻžāĻĻā§āĻ° āĻā§āĻŦāĻŋāĻ˛ā§ āĻĒā§āĻ°āĻŦāĻžāĻšāĻŋāĻ¤ āĻšāĻ¯āĻŧāĨ¤ āĻāĻāĻŋ āĻĒāĻ°ā§āĻā§āĻˇāĻž āĻāĻ°āĻžāĻ° āĻāĻ¨ā§āĻ¯, āĻāĻŽāĻ°āĻž BigQuery-āĻ āĻ¯ā§āĻ¤ā§ āĻĒāĻžāĻ°āĻŋ āĻāĻŦāĻ āĻĄā§āĻāĻž āĻĻā§āĻāĻ¤ā§ āĻĒāĻžāĻ°āĻŋāĨ¤ āĻ¨ā§āĻā§āĻ° āĻāĻŽāĻžāĻ¨ā§āĻĄāĻāĻŋ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°āĻžāĻ° āĻĒāĻ°ā§ āĻāĻĒāĻ¨āĻŋ āĻĄā§āĻāĻžāĻ¸ā§āĻā§āĻ° āĻĒā§āĻ°āĻĨāĻŽ āĻāĻ¯āĻŧā§āĻāĻāĻŋ āĻ¸āĻžāĻ°āĻŋ āĻĻā§āĻāĻ¤ā§ āĻĒāĻžāĻŦā§āĻ¨āĨ¤ āĻāĻāĻ¨ āĻ¯ā§āĻšā§āĻ¤ā§ āĻāĻŽāĻžāĻĻā§āĻ° āĻāĻžāĻā§ BigQuery-āĻ āĻĄā§āĻāĻž āĻ¸āĻāĻ°āĻā§āĻˇāĻŋāĻ¤ āĻāĻā§, āĻāĻŽāĻ°āĻž āĻāĻ°āĻ āĻŦāĻŋāĻļā§āĻ˛ā§āĻˇāĻŖ āĻāĻ°āĻ¤ā§ āĻĒāĻžāĻ°āĻŋ, āĻ¸ā§āĻāĻ¸āĻžāĻĨā§ āĻ¸āĻšāĻāĻ°ā§āĻŽā§āĻĻā§āĻ° āĻ¸āĻžāĻĨā§ āĻĄā§āĻāĻž āĻļā§āĻ¯āĻŧāĻžāĻ° āĻāĻ°āĻ¤ā§ āĻĒāĻžāĻ°āĻŋ āĻāĻŦāĻ āĻŦā§āĻ¯āĻŦāĻ¸āĻžāĻ¯āĻŧāĻŋāĻ āĻĒā§āĻ°āĻļā§āĻ¨ā§āĻ° āĻāĻ¤ā§āĻ¤āĻ° āĻĻā§āĻāĻ¯āĻŧāĻž āĻļā§āĻ°ā§ āĻāĻ°āĻ¤ā§ āĻĒāĻžāĻ°āĻŋāĨ¤
SELECT * FROM `user-logs-237110.userlogs.logdata` LIMIT 10;
āĻāĻŋāĻ¤ā§āĻ° 5: BigQuery
āĻāĻĒāĻ¸āĻāĻšāĻžāĻ°
āĻāĻŽāĻ°āĻž āĻāĻļāĻž āĻāĻ°āĻŋ āĻāĻ āĻĒā§āĻ¸ā§āĻāĻāĻŋ āĻāĻāĻāĻŋ āĻ¸ā§āĻā§āĻ°āĻŋāĻŽāĻŋāĻ āĻĄā§āĻāĻž āĻĒāĻžāĻāĻĒāĻ˛āĻžāĻāĻ¨ āĻ¤ā§āĻ°āĻŋ āĻāĻ°āĻžāĻ° āĻĒāĻžāĻļāĻžāĻĒāĻžāĻļāĻŋ āĻĄā§āĻāĻž āĻāĻ°āĻ āĻ ā§āĻ¯āĻžāĻā§āĻ¸ā§āĻ¸āĻ¯ā§āĻā§āĻ¯ āĻāĻ°āĻžāĻ° āĻāĻĒāĻžāĻ¯āĻŧāĻā§āĻ˛āĻŋ āĻā§āĻāĻā§ āĻŦā§āĻ° āĻāĻ°āĻžāĻ° āĻāĻāĻāĻŋ āĻĻāĻ°āĻāĻžāĻ°ā§ āĻāĻĻāĻžāĻšāĻ°āĻŖ āĻšāĻŋāĻ¸āĻžāĻŦā§ āĻāĻžāĻ āĻāĻ°ā§ā§ˇ āĻāĻ āĻŦāĻŋāĻ¨ā§āĻ¯āĻžāĻ¸ā§ āĻĄā§āĻāĻž āĻ¸āĻāĻ°āĻā§āĻˇāĻŖ āĻāĻ°āĻž āĻāĻŽāĻžāĻĻā§āĻ° āĻ āĻ¨ā§āĻ āĻ¸ā§āĻŦāĻŋāĻ§āĻž āĻĻā§āĻ¯āĻŧāĨ¤ āĻāĻāĻ¨ āĻāĻŽāĻ°āĻž āĻā§āĻ°ā§āĻ¤ā§āĻŦāĻĒā§āĻ°ā§āĻŖ āĻĒā§āĻ°āĻļā§āĻ¨ā§āĻ° āĻāĻ¤ā§āĻ¤āĻ° āĻĻā§āĻāĻ¯āĻŧāĻž āĻļā§āĻ°ā§ āĻāĻ°āĻ¤ā§ āĻĒāĻžāĻ°āĻŋ āĻ¯ā§āĻŽāĻ¨ āĻāĻ¤āĻāĻ¨ āĻŽāĻžāĻ¨ā§āĻˇ āĻāĻŽāĻžāĻĻā§āĻ° āĻĒāĻŖā§āĻ¯ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°āĻā§? āĻāĻĒāĻ¨āĻžāĻ° āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ°āĻāĻžāĻ°ā§ āĻŦā§āĻ¸ āĻ¸āĻŽāĻ¯āĻŧā§āĻ° āĻ¸āĻžāĻĨā§ āĻŦāĻžāĻĄāĻŧāĻā§? āĻĒāĻŖā§āĻ¯ā§āĻ° āĻā§āĻ¨ āĻĻāĻŋāĻāĻā§āĻ˛āĻŋāĻ° āĻ¸āĻžāĻĨā§ āĻ˛ā§āĻā§āĻ°āĻž āĻ¸āĻŦāĻā§āĻ¯āĻŧā§ āĻŦā§āĻļāĻŋ āĻ¯ā§āĻāĻžāĻ¯ā§āĻ āĻāĻ°ā§? āĻāĻŦāĻ āĻ¸ā§āĻāĻžāĻ¨ā§ āĻ¤ā§āĻ°ā§āĻāĻŋ āĻāĻā§ āĻ¯ā§āĻāĻžāĻ¨ā§ āĻĨāĻžāĻāĻž āĻāĻāĻŋāĻ¤ āĻ¨āĻ¯āĻŧ? āĻāĻ āĻĒā§āĻ°āĻļā§āĻ¨āĻā§āĻ˛ā§ āĻĒā§āĻ°āĻ¤āĻŋāĻˇā§āĻ āĻžāĻ¨ā§āĻ° āĻ¸ā§āĻŦāĻžāĻ°ā§āĻĨā§āĻ° āĻšāĻŦā§āĨ¤ āĻāĻ āĻĒā§āĻ°āĻļā§āĻ¨āĻā§āĻ˛āĻŋāĻ° āĻāĻ¤ā§āĻ¤āĻ° āĻĨā§āĻā§ āĻāĻĻā§āĻā§āĻ¤ āĻ āĻ¨ā§āĻ¤āĻ°ā§āĻĻā§āĻˇā§āĻāĻŋāĻā§āĻ˛āĻŋāĻ° āĻāĻĒāĻ° āĻāĻŋāĻ¤ā§āĻ¤āĻŋ āĻāĻ°ā§, āĻāĻŽāĻ°āĻž āĻĒāĻŖā§āĻ¯āĻāĻŋāĻā§ āĻāĻ¨ā§āĻ¨āĻ¤ āĻāĻ°āĻ¤ā§ āĻāĻŦāĻ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ°āĻāĻžāĻ°ā§āĻ° āĻŦā§āĻ¯āĻ¸ā§āĻ¤āĻ¤āĻž āĻŦāĻžāĻĄāĻŧāĻžāĻ¤ā§ āĻĒāĻžāĻ°āĻŋāĨ¤
āĻ°āĻļā§āĻŽāĻŋ āĻāĻ āĻ§āĻ°āĻ¨ā§āĻ° āĻŦā§āĻ¯āĻžāĻ¯āĻŧāĻžāĻŽā§āĻ° āĻāĻ¨ā§āĻ¯ āĻ¸āĻ¤ā§āĻ¯āĻŋāĻ āĻāĻĒāĻ¯ā§āĻā§ āĻāĻŦāĻ āĻ āĻ¨ā§āĻ¯āĻžāĻ¨ā§āĻ¯ āĻāĻāĻ°ā§āĻˇāĻŖā§āĻ¯āĻŧ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ°ā§āĻ° āĻā§āĻˇā§āĻ¤ā§āĻ°ā§āĻ āĻ°āĻ¯āĻŧā§āĻā§āĨ¤ āĻāĻĻāĻžāĻšāĻ°āĻŖāĻ¸ā§āĻŦāĻ°ā§āĻĒ, āĻāĻĒāĻ¨āĻŋ āĻ°āĻŋāĻ¯āĻŧā§āĻ˛ āĻāĻžāĻāĻŽā§ āĻ¸ā§āĻāĻ āĻāĻŋāĻ āĻĄā§āĻāĻž āĻŦāĻŋāĻļā§āĻ˛ā§āĻˇāĻŖ āĻāĻ°āĻ¤ā§ āĻāĻŦāĻ āĻŦāĻŋāĻļā§āĻ˛ā§āĻˇāĻŖā§āĻ° āĻāĻĒāĻ° āĻāĻŋāĻ¤ā§āĻ¤āĻŋ āĻāĻ°ā§ āĻŦā§āĻ¯āĻŦāĻ¸āĻž āĻāĻ°āĻ¤ā§ āĻāĻžāĻāĻ¤ā§ āĻĒāĻžāĻ°ā§āĻ¨, āĻ¸āĻŽā§āĻāĻŦāĻ¤ āĻāĻĒāĻ¨āĻžāĻ° āĻāĻžāĻā§ āĻ¯āĻžāĻ¨āĻŦāĻžāĻšāĻ¨ āĻĨā§āĻā§ āĻ¸ā§āĻ¨ā§āĻ¸āĻ° āĻĄā§āĻāĻž āĻāĻ¸āĻā§ āĻāĻŦāĻ āĻāĻĒāĻ¨āĻŋ āĻā§āĻ°ā§āĻ¯āĻžāĻĢāĻŋāĻ āĻ¸ā§āĻ¤āĻ°ā§āĻ° āĻāĻŖāĻ¨āĻž āĻāĻ°āĻ¤ā§ āĻāĻžāĻ¨āĨ¤ āĻāĻĻāĻžāĻšāĻ°āĻŖāĻ¸ā§āĻŦāĻ°ā§āĻĒ, āĻāĻĒāĻ¨āĻŋ āĻāĻāĻāĻŋ āĻā§āĻŽāĻŋāĻ āĻā§āĻŽā§āĻĒāĻžāĻ¨āĻŋ āĻšāĻ¤ā§ āĻĒāĻžāĻ°ā§āĻ¨ āĻ¯āĻž āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ°āĻāĻžāĻ°ā§āĻ° āĻĄā§āĻāĻž āĻ¸āĻāĻā§āĻ°āĻš āĻāĻ°ā§ āĻāĻŦāĻ āĻŽā§āĻ˛ āĻŽā§āĻā§āĻ°āĻŋāĻā§āĻ¸ āĻā§āĻ°ā§āĻ¯āĻžāĻ āĻāĻ°āĻ¤ā§ āĻĄā§āĻ¯āĻžāĻļāĻŦā§āĻ°ā§āĻĄ āĻ¤ā§āĻ°āĻŋ āĻāĻ°āĻ¤ā§ āĻāĻāĻŋ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§āĨ¤ āĻ āĻŋāĻ āĻāĻā§, āĻāĻĻā§āĻ°āĻ˛ā§āĻ, āĻāĻāĻŋ āĻ āĻ¨ā§āĻ¯ āĻĒā§āĻ¸ā§āĻā§āĻ° āĻāĻ¨ā§āĻ¯ āĻāĻāĻāĻŋ āĻŦāĻŋāĻˇāĻ¯āĻŧ, āĻĒāĻĄāĻŧāĻžāĻ° āĻāĻ¨ā§āĻ¯ āĻ§āĻ¨ā§āĻ¯āĻŦāĻžāĻĻ, āĻāĻŦāĻ āĻ¯āĻžāĻ°āĻž āĻ¸āĻŽā§āĻĒā§āĻ°ā§āĻŖ āĻā§āĻĄ āĻĻā§āĻāĻ¤ā§ āĻāĻžāĻ¨ āĻ¤āĻžāĻĻā§āĻ° āĻāĻ¨ā§āĻ¯, āĻ¨ā§āĻā§ āĻāĻŽāĻžāĻ° āĻāĻŋāĻāĻšāĻžāĻŦā§āĻ° āĻ˛āĻŋāĻā§āĻ āĻ°āĻ¯āĻŧā§āĻā§āĨ¤
āĻāĻāĻžāĻ¨ā§āĻ āĻļā§āĻˇ.
āĻāĻ¤ā§āĻ¸: www.habr.com