জাভাতে জেনারেটিভ এআই অ্যাপ্লিকেশনের জন্য ব্যবহারিক পর্যবেক্ষণ কৌশল

১. সংক্ষিপ্ত বিবরণ

অন্যান্য অ্যাপ্লিকেশনের মতোই জেনারেটিভ এআই অ্যাপ্লিকেশনের জন্যও পর্যবেক্ষণযোগ্যতা প্রয়োজন। জেনারেটিভ এআই-এর জন্য কি কোনো বিশেষ পর্যবেক্ষণ কৌশল প্রয়োজন?

এই ল্যাবে, আপনি একটি সাধারণ Gen AI অ্যাপ্লিকেশন তৈরি করবেন। এটিকে Cloud Run- এ ডেপ্লয় করুন। এবং Google Cloud-এর অবজার্ভেবিলিটি পরিষেবা ও পণ্য ব্যবহার করে এতে প্রয়োজনীয় মনিটরিং ও লগিং সক্ষমতা যুক্ত করুন।

আপনি যা শিখবেন

  • ভার্টেক্স এআই ও ক্লাউড শেল এডিটর ব্যবহার করে এমন একটি অ্যাপ্লিকেশন লিখুন।
  • আপনার অ্যাপ্লিকেশন কোড গিটহাবে সংরক্ষণ করুন
  • আপনার অ্যাপ্লিকেশনের সোর্স কোড ক্লাউড রান-এ ডেপ্লয় করতে gcloud CLI ব্যবহার করুন।
  • আপনার Gen AI অ্যাপ্লিকেশনে মনিটরিং এবং লগিং সক্ষমতা যোগ করুন
  • লগ-ভিত্তিক মেট্রিক ব্যবহার করে
  • ওপেন টেলিমেট্রি এসডিকে ব্যবহার করে লগিং ও মনিটরিং বাস্তবায়ন
  • দায়িত্বশীল এআই ডেটা পরিচালনা সম্পর্কে অন্তর্দৃষ্টি লাভ করুন

২. পূর্বশর্তসমূহ

যদি আপনার আগে থেকে কোনো গুগল অ্যাকাউন্ট না থাকে, তাহলে আপনাকে একটি নতুন অ্যাকাউন্ট তৈরি করতে হবে।

৩. প্রজেক্ট সেটআপ

  1. আপনার গুগল অ্যাকাউন্ট দিয়ে গুগল ক্লাউড কনসোলে সাইন-ইন করুন।
  2. একটি নতুন প্রজেক্ট তৈরি করুন অথবা বিদ্যমান কোনো প্রজেক্ট পুনরায় ব্যবহার করুন। আপনি এইমাত্র যে প্রজেক্টটি তৈরি বা নির্বাচন করেছেন, তার প্রজেক্ট আইডিটি লিখে রাখুন।
  3. প্রকল্পটির জন্য বিলিং চালু করুন
    • এই ল্যাবটি সম্পন্ন করতে বিলিং খরচ ৫ ডলারের কম হওয়া উচিত।
    • পরবর্তী চার্জ এড়াতে, এই ল্যাবের শেষে দেওয়া ধাপগুলো অনুসরণ করে আপনি রিসোর্সগুলো মুছে ফেলতে পারেন।
    • নতুন ব্যবহারকারীরা ৩০০ মার্কিন ডলারের ফ্রি ট্রায়ালের জন্য যোগ্য।
  4. ক্লাউড বিলিং-এর 'আমার প্রোজেক্ট' -এ বিলিং নিশ্চিতকরণ সক্রিয় করা আছে।
    • যদি আপনার নতুন প্রজেক্টের Billing account কলামে Billing is disabled :
      1. Actions কলামে থাকা তিনটি ডটে ক্লিক করুন।
      2. বিলিং পরিবর্তন করতে ক্লিক করুন
      3. আপনি যে বিলিং অ্যাকাউন্টটি ব্যবহার করতে চান তা নির্বাচন করুন।
    • আপনি যদি কোনো লাইভ ইভেন্টে অংশগ্রহণ করেন, তাহলে অ্যাকাউন্টটির নাম সম্ভবত Google Cloud Platform Trial Billing Account হবে।

৪. ক্লাউড শেল এডিটর প্রস্তুত করুন

  1. ক্লাউড শেল এডিটর- এ যান। যদি আপনার ক্রেডেনশিয়াল ব্যবহার করে gcloud কল করার জন্য ক্লাউড শেলকে অনুমোদন দিতে অনুরোধ করে নিম্নলিখিত বার্তাটি আসে, তবে চালিয়ে যাওয়ার জন্য Authorize-এ ক্লিক করুন।
    ক্লাউড শেল অনুমোদন করতে ক্লিক করুন
  2. টার্মিনাল উইন্ডো খুলুন
    1. হ্যামবার্গার মেনুতে ক্লিক করুন হ্যামবার্গার মেনু আইকন
    2. টার্মিনালে ক্লিক করুন
    3. নতুন টার্মিনালে ক্লিক করুন
      ক্লাউড শেল এডিটরে নতুন টার্মিনাল খুলুন
  3. টার্মিনালে আপনার প্রজেক্ট আইডি কনফিগার করুন:
    gcloud config set project [PROJECT_ID]
    
    [PROJECT_ID] এর জায়গায় আপনার প্রোজেক্টের আইডি বসান। উদাহরণস্বরূপ, যদি আপনার প্রোজেক্ট আইডি lab-example-project হয়, তাহলে কমান্ডটি হবে:
    gcloud config set project lab-project-id-example
    
    যদি আপনার সামনে এই বার্তাটি আসে যে gcloud, GCPI API-এর জন্য আপনার ক্রেডেনশিয়াল চাইছে, তাহলে চালিয়ে যাওয়ার জন্য Authorize-এ ক্লিক করুন।
    ক্লাউড শেল অনুমোদন করতে ক্লিক করুন
    সফলভাবে কার্যকর হলে আপনি নিম্নলিখিত বার্তাটি দেখতে পাবেন:
    Updated property [core/project].
    
    যদি আপনি একটি WARNING দেখতে পান এবং আপনাকে Do you want to continue (Y/N)? জিজ্ঞাসা করা হয়, তাহলে সম্ভবত আপনি প্রজেক্ট আইডি ভুলভাবে প্রবেশ করিয়েছেন। N চাপুন, Enter চাপুন এবং সঠিক প্রজেক্ট আইডি খুঁজে পাওয়ার পর gcloud config set project কমান্ডটি আবার চালানোর চেষ্টা করুন।
  4. (ঐচ্ছিক) প্রজেক্ট আইডি খুঁজে পেতে সমস্যা হলে, আপনার সমস্ত প্রজেক্টের আইডি তৈরির সময় অনুসারে অবরোহী ক্রমে দেখতে নিম্নলিখিত কমান্ডটি চালান:
    gcloud projects list \
         --format='value(projectId,createTime)' \
         --sort-by=~createTime
    

৫. গুগল এপিআই সক্রিয় করুন

টার্মিনালে, এই ল্যাবের জন্য প্রয়োজনীয় গুগল এপিআইগুলো সক্রিয় করুন:

gcloud services enable \
     run.googleapis.com \
     cloudbuild.googleapis.com \
     aiplatform.googleapis.com \
     logging.googleapis.com \
     monitoring.googleapis.com \
     cloudtrace.googleapis.com

এই কমান্ডটি সম্পন্ন হতে কিছুটা সময় লাগবে। অবশেষে, এটি এই ধরনের একটি সফলতার বার্তা তৈরি করবে:

Operation "operations/acf.p2-73d90d00-47ee-447a-b600" finished successfully.

যদি আপনি ERROR: (gcloud.services.enable) HttpError accessing দিয়ে শুরু হওয়া এবং নীচের মতো ত্রুটির বিবরণ সম্বলিত কোনো ত্রুটি বার্তা পান, তাহলে ১-২ মিনিট বিরতি দিয়ে কমান্ডটি পুনরায় চেষ্টা করুন।

"error": {
  "code": 429,
  "message": "Quota exceeded for quota metric 'Mutate requests' and limit 'Mutate requests per minute' of service 'serviceusage.googleapis.com' ...",
  "status": "RESOURCE_EXHAUSTED",
  ...
}

৬. একটি জেন ​​এআই অ্যাপ্লিকেশন তৈরি করুন

এই ধাপে আপনি একটি সাধারণ অনুরোধ-ভিত্তিক অ্যাপ্লিকেশনের কোড লিখবেন, যা জেমিনি মডেল ব্যবহার করে আপনার পছন্দের একটি প্রাণী সম্পর্কে ১০টি মজার তথ্য দেখাবে। অ্যাপ্লিকেশন কোডটি তৈরি করতে নিম্নলিখিত পদক্ষেপগুলো অনুসরণ করুন।

  1. টার্মিনালে codelab-o11y ডিরেক্টরিটি তৈরি করুন:
    mkdir "${HOME}/codelab-o11y"
    
  2. বর্তমান ডিরেক্টরি codelab-o11y তে পরিবর্তন করুন:
    cd "${HOME}/codelab-o11y"
    
  3. স্প্রিং ফ্রেমওয়ার্ক স্টার্টার ব্যবহার করে জাভা অ্যাপ্লিকেশনটির বুটস্ট্র্যাপ কোড ডাউনলোড করুন:
    curl https://start.spring.io/starter.zip \
        -d dependencies=web \
        -d javaVersion=17 \
        -d type=maven-project \
        -d bootVersion=3.4.1 -o java-starter.zip
    
  4. বুটস্ট্র্যাপ কোডটি বর্তমান ফোল্ডারে আনআর্কাইভ করুন:
    unzip java-starter.zip
    
  5. এবং ফোল্ডার থেকে আর্কাইভ ফাইলটি মুছে ফেলুন:
    rm java-starter.zip
    
  6. ক্লাউড রানে কোড ডেপ্লয় করার সময় কোন জাভা রানটাইম ভার্সন ব্যবহার করা হবে তা নির্ধারণ করতে project.toml ফাইল তৈরি করুন:
    cat > "${HOME}/codelab-o11y/project.toml" << EOF
    [[build.env]]
        name = "GOOGLE_RUNTIME_VERSION"
        value = "17"
    EOF
    
  7. pom.xml ফাইলে Google Cloud SDK নির্ভরতাগুলো যোগ করুন:
    1. Google Cloud Core প্যাকেজ যোগ করুন:
      sed -i 's/<dependencies>/<dependencies>\
      \
              <dependency>\
                  <groupId>com.google.cloud<\/groupId>\
                  <artifactId>google-cloud-core<\/artifactId>\
                  <version>2.49.1<\/version>\
              <\/dependency>\
              /g' "${HOME}/codelab-o11y/pom.xml"
      
    2. Google Cloud Vertex AI প্যাকেজ যোগ করুন:
      sed -i 's/<dependencies>/<dependencies>\
      \
              <dependency>\
                  <groupId>com.google.cloud<\/groupId>\
                  <artifactId>google-cloud-vertexai<\/artifactId>\
                  <version>1.16.0<\/version>\
              <\/dependency>\
              /g' "${HOME}/codelab-o11y/pom.xml"
      
  8. ক্লাউড শেল এডিটরে DemoApplication.java ফাইলটি খুলুন:
    cloudshell edit "${HOME}/codelab-o11y/src/main/java/com/example/demo/DemoApplication.java"
    
    এখন টার্মিনালের উপরের এডিটর উইন্ডোতে DemoApplication.java ফাইলটির একটি কাঠামোবদ্ধ সোর্স কোড দেখা যাবে। ফাইলটির সোর্স কোডটি নিচের মতো হবে:
    package com.example.demo;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class DemoApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(DemoApplication.class, args);
        }
    }
    
  9. এডিটরের কোডটি নিচে দেখানো সংস্করণ দিয়ে প্রতিস্থাপন করুন। কোডটি প্রতিস্থাপন করতে, ফাইলটির ভেতরের সবকিছু মুছে ফেলুন এবং তারপর নিচের কোডটি এডিটরে কপি করুন:
    package com.example.demo;
    
    import java.io.IOException;
    import java.util.Collections;
    
    import javax.annotation.PostConstruct;
    import javax.annotation.PreDestroy;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    
    import com.google.cloud.ServiceOptions;
    import com.google.cloud.vertexai.VertexAI;
    import com.google.cloud.vertexai.api.GenerateContentResponse;
    import com.google.cloud.vertexai.generativeai.GenerativeModel;
    import com.google.cloud.vertexai.generativeai.ResponseHandler;
    
    @SpringBootApplication
    public class DemoApplication {
    
        public static void main(String[] args) {
            String port = System.getenv().getOrDefault("PORT", "8080");
            SpringApplication app = new SpringApplication(DemoApplication.class);
            app.setDefaultProperties(Collections.singletonMap("server.port", port));
            app.run(args);
        }
    }
    
    @RestController
    class HelloController {
        private final String projectId = ServiceOptions.getDefaultProjectId();
        private VertexAI vertexAI;
        private GenerativeModel model;
    
        @PostConstruct
        public void init() {
            vertexAI = new VertexAI(projectId, "us-central1");
            model = new GenerativeModel("gemini-1.5-flash", vertexAI);
        }
    
        @PreDestroy
        public void destroy() {
            vertexAI.close();
        }
    
        @GetMapping("/")
        public String getFacts(@RequestParam(defaultValue = "dog") String animal) throws IOException {
            String prompt = "Give me 10 fun facts about " + animal + ". Return this as html without backticks.";
            GenerateContentResponse response = model.generateContent(prompt);
            return ResponseHandler.getText(response);
        }
    }
    
    কয়েক সেকেন্ড পর ক্লাউড শেল এডিটর আপনার কোড স্বয়ংক্রিয়ভাবে সংরক্ষণ করবে।

Gen AI অ্যাপ্লিকেশনটির কোড Cloud Run-এ ডেপ্লয় করুন।

  1. টার্মিনাল উইন্ডোতে অ্যাপ্লিকেশনটির সোর্স কোড ক্লাউড রান-এ ডেপ্লয় করার জন্য কমান্ডটি চালান।
    gcloud run deploy codelab-o11y-service \
         --source="${HOME}/codelab-o11y/" \
         --region=us-central1 \
         --allow-unauthenticated
    
    যদি আপনি নিচের মতো একটি প্রম্পট দেখতে পান, যা আপনাকে জানাচ্ছে যে কমান্ডটি একটি নতুন রিপোজিটরি তৈরি করবে, তাহলে Enter চাপুন।
    Deploying from source requires an Artifact Registry Docker repository to store built containers.
    A repository named [cloud-run-source-deploy] in region [us-central1] will be created.
    
    Do you want to continue (Y/n)?
    
    ডেপ্লয়মেন্ট প্রক্রিয়াটিতে কয়েক মিনিট পর্যন্ত সময় লাগতে পারে। ডেপ্লয়মেন্ট প্রক্রিয়াটি সম্পন্ন হওয়ার পর আপনি নিচের মতো আউটপুট দেখতে পাবেন:
    Service [codelab-o11y-service] revision [codelab-o11y-service-00001-t2q] has been deployed and is serving 100 percent of traffic.
    Service URL: https://codelab-o11y-service-12345678901.us-central1.run.app
    
  2. প্রদর্শিত ক্লাউড রান সার্ভিস ইউআরএলটি আপনার ব্রাউজারের একটি আলাদা ট্যাব বা উইন্ডোতে কপি করুন। বিকল্পভাবে, সার্ভিস ইউআরএলটি প্রিন্ট করার জন্য টার্মিনালে নিম্নলিখিত কমান্ডটি চালান এবং ইউআরএলটি খোলার জন্য Ctrl কী চেপে ধরে প্রদর্শিত ইউআরএলটিতে ক্লিক করুন:
    gcloud run services list \
         --format='value(URL)' \
         --filter='SERVICE:"codelab-o11y-service"'
    
    যখন ইউআরএলটি খোলা হবে, তখন আপনি 500 এরর পেতে পারেন অথবা এই মেসেজটি দেখতে পারেন:
    Sorry, this is just a placeholder...
    
    এর মানে হলো, সার্ভিসটির ডেপ্লয়মেন্ট সম্পূর্ণ হয়নি। কিছুক্ষণ অপেক্ষা করুন এবং পেজটি রিফ্রেশ করুন। শেষে আপনি ‘Fun Dog Facts’ দিয়ে শুরু হওয়া একটি লেখা দেখতে পাবেন, যেখানে কুকুর সম্পর্কে ১০টি মজার তথ্য থাকবে।

বিভিন্ন প্রাণী সম্পর্কে মজার তথ্য পেতে অ্যাপ্লিকেশনটি ব্যবহার করে দেখুন। এটি করার জন্য URL-এর শেষে animal প্যারামিটারটি যুক্ত করুন, যেমন ?animal=[ANIMAL] যেখানে [ANIMAL] হলো একটি প্রাণীর নাম। উদাহরণস্বরূপ, বিড়াল সম্পর্কে ১০টি মজার তথ্য পেতে ?animal=cat যুক্ত করুন অথবা সামুদ্রিক কচ্ছপ সম্পর্কে ১০টি মজার তথ্য পেতে ?animal=sea turtle যুক্ত করুন।

৭. আপনার Vertex API কলগুলো নিরীক্ষা করুন

গুগল এপিআই কল অডিট করলে "কে, কোথায় এবং কখন একটি নির্দিষ্ট এপিআই কল করছে?"-এর মতো প্রশ্নের উত্তর পাওয়া যায়। আপনার অ্যাপ্লিকেশনের সমস্যা সমাধান, রিসোর্স ব্যবহারের তদন্ত বা সফটওয়্যার ফরেনসিক বিশ্লেষণ করার সময় অডিটিং গুরুত্বপূর্ণ।

অডিট লগ আপনাকে প্রশাসনিক ও সিস্টেম কার্যকলাপ ট্র্যাক করার পাশাপাশি 'ডেটা রিড' এবং 'ডেটা রাইট' এপিআই অপারেশনের কলগুলো লগ করতে দেয়। কন্টেন্ট তৈরির জন্য Vertex AI-এর অনুরোধগুলো অডিট করতে হলে আপনাকে ক্লাউড কনসোলে 'ডেটা রিড' অডিট লগ চালু করতে হবে।

  1. ক্লাউড কনসোলে অডিট লগ পৃষ্ঠাটি খুলতে নিচের বোতামে ক্লিক করুন।

  2. নিশ্চিত করুন যে পেজটিতে এই ল্যাবের জন্য আপনার তৈরি করা প্রজেক্টটি সিলেক্ট করা আছে। সিলেক্ট করা প্রজেক্টটি পেজের উপরের বাম কোণে হ্যামবার্গার মেনু থেকেই দেখানো হয়:
    গুগল ক্লাউড কনসোল প্রজেক্ট ড্রপডাউন
    প্রয়োজন হলে কম্বোবক্স থেকে সঠিক প্রজেক্টটি নির্বাচন করুন।
  3. ডেটা অ্যাক্সেস অডিট লগ কনফিগারেশন টেবিলের সার্ভিস কলামে, Vertex AI API সার্ভিসটি খুঁজুন এবং সার্ভিসের নামের বাম পাশে অবস্থিত চেকবক্সটি সিলেক্ট করে সার্ভিসটি নির্বাচন করুন।
    ভার্টেক্স এআই এপিআই নির্বাচন করুন
  4. ডানদিকের তথ্য প্যানেলে, "ডেটা রিড" অডিট টাইপটি নির্বাচন করুন।
    ডেটা রিড লগ চেক করুন
  5. সংরক্ষণ করুন- এ ক্লিক করুন।

অডিট লগ তৈরি করতে সার্ভিস ইউআরএলটি খুলুন। ভিন্ন ভিন্ন ফলাফল পেতে ?animal= প্যারামিটারের মান পরিবর্তন করার সময় পেজটি রিফ্রেশ করুন।

অডিট লগগুলি অন্বেষণ করুন

  1. ক্লাউড কনসোলে লগস এক্সপ্লোরার পৃষ্ঠাটি খুলতে নিচের বোতামে ক্লিক করুন:

  2. নিম্নলিখিত ফিল্টারটি কোয়েরি প্যানে পেস্ট করুন।
    LOG_ID("cloudaudit.googleapis.com%2Fdata_access") AND
    protoPayload.serviceName="aiplatform.googleapis.com"
    
    কোয়েরি পেইন হলো লগস এক্সপ্লোরার পেজের উপরের দিকে অবস্থিত একটি এডিটর:
    অডিট লগ অনুসন্ধান করুন
  3. রান কোয়েরি-তে ক্লিক করুন।
  4. অডিট লগ এন্ট্রিগুলোর মধ্যে একটি নির্বাচন করুন এবং লগে সংরক্ষিত তথ্য পরীক্ষা করার জন্য ফিল্ডগুলো প্রসারিত করুন।
    আপনি ব্যবহৃত মেথড এবং মডেল সহ ভার্টেক্স এপিআই কল সম্পর্কিত বিস্তারিত তথ্য দেখতে পারেন। এছাড়াও আপনি আহ্বানকারীর পরিচয় এবং কোন অনুমতিগুলো কলটিকে অনুমোদন দিয়েছে, তাও দেখতে পারেন।

৮. জেন এআই-এর সাথে মিথস্ক্রিয়া নথিভুক্ত করুন

অডিট লগে এপিআই অনুরোধের প্যারামিটার বা প্রতিক্রিয়ার ডেটা পাওয়া যায় না। তবে, অ্যাপ্লিকেশন ট্রাবলশুটিং এবং ওয়ার্কফ্লো বিশ্লেষণের জন্য এই তথ্য গুরুত্বপূর্ণ হতে পারে। এই ধাপে আমরা অ্যাপ্লিকেশন লগিং যোগ করে এই ঘাটতি পূরণ করব।

এই ইমপ্লিমেন্টেশনে অ্যাপ্লিকেশন লগ স্ট্যান্ডার্ড আউটপুটে প্রিন্ট করার জন্য Spring Boot-এর সাথে Logback ব্যবহার করা হয়। এই পদ্ধতিতে Cloud Run-এর একটি বিশেষ সুবিধা রয়েছে, যার মাধ্যমে স্ট্যান্ডার্ড আউটপুটে প্রিন্ট হওয়া তথ্য ক্যাপচার করে স্বয়ংক্রিয়ভাবে Cloud Logging-এ অন্তর্ভুক্ত করা হয়। তথ্যকে স্ট্রাকচার্ড ডেটা হিসেবে ক্যাপচার করার জন্য, প্রিন্ট করা লগগুলোকে সেই অনুযায়ী ফরম্যাট করা উচিত। অ্যাপ্লিকেশনে স্ট্রাকচার্ড লগিং সক্ষমতা যোগ করতে নিচের নির্দেশাবলী অনুসরণ করুন।

  1. আপনার ব্রাউজারের 'ক্লাউড শেল' উইন্ডোতে (বা ট্যাবে) ফিরে যান।
  2. ক্লাউড শেল এডিটরে LoggingEventGoogleCloudEncoder.java নামে একটি নতুন ফাইল তৈরি করে খুলুন:
    cloudshell edit "${HOME}/codelab-o11y/src/main/java/com/example/demo/LoggingEventGoogleCloudEncoder.java"
    
  3. গুগল ক্লাউড স্ট্রাকচার্ড লগ ফরম্যাট অনুসরণ করে লগটিকে স্ট্রিংফাই করা JSON হিসেবে এনকোড করার জন্য Logback এনকোডার প্রয়োগ করতে নিম্নলিখিত কোডটি কপি ও পেস্ট করুন:
    package com.example.demo;
    
    import static ch.qos.logback.core.CoreConstants.UTF_8_CHARSET;
    
    import java.time.Instant;
    import ch.qos.logback.core.encoder.EncoderBase;
    import ch.qos.logback.classic.Level;
    import ch.qos.logback.classic.spi.ILoggingEvent;
    import java.util.HashMap;
    
    import com.google.gson.Gson;
    
    public class LoggingEventGoogleCloudEncoder extends EncoderBase<ILoggingEvent>  {
        private static final byte[] EMPTY_BYTES = new byte[0];
        private final Gson gson = new Gson();
    
        @Override
        public byte[] headerBytes() {
            return EMPTY_BYTES;
        }
    
        @Override
        public byte[] encode(ILoggingEvent e) {
            var timestamp = Instant.ofEpochMilli(e.getTimeStamp());
            var fields = new HashMap<String, Object>() {
                {
                    put("timestamp", timestamp.toString());
                    put("severity", severityFor(e.getLevel()));
                    put("message", e.getMessage());
                }
            };
            var params = e.getKeyValuePairs();
            if (params != null && params.size() > 0) {
                params.forEach(kv -> fields.putIfAbsent(kv.key, kv.value));
            }
            var data = gson.toJson(fields) + "\n";
            return data.getBytes(UTF_8_CHARSET);
        }
    
        @Override
        public byte[] footerBytes() {
            return EMPTY_BYTES;
        }
    
        private static String severityFor(Level level) {
            switch (level.toInt()) {
                case Level.TRACE_INT:
                return "DEBUG";
                case Level.DEBUG_INT:
                return "DEBUG";
                case Level.INFO_INT:
                return "INFO";
                case Level.WARN_INT:
                return "WARNING";
                case Level.ERROR_INT:
                return "ERROR";
                default:
                return "DEFAULT";
            }
        }
    }
    
  4. ক্লাউড শেল এডিটরে logback.xml নামে একটি নতুন ফাইল তৈরি করে খুলুন:
    cloudshell edit "${HOME}/codelab-o11y/src/main/resources/logback.xml"
    
  5. স্ট্যান্ডার্ড আউটপুটে লগ প্রিন্ট করে এমন লগব্যাক অ্যাপেন্ডারের সাথে এনকোডার ব্যবহার করার জন্য লগব্যাক কনফিগার করতে নিম্নলিখিত XML-টি কপি ও পেস্ট করুন:
    <?xml version="1.0" encoding="UTF-8"?>
    <configuration debug="true">
        <appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
            <encoder class="com.example.demo.LoggingEventGoogleCloudEncoder"/>
        </appender>
    
        <root level="info">
            <appender-ref ref="Console" />
        </root>
    </configuration>
    
  6. ক্লাউড শেল এডিটরে DemoApplication.java ফাইলটি পুনরায় খুলুন:
    cloudshell edit "${HOME}/codelab-o11y/src/main/java/com/example/demo/DemoApplication.java"
    
  7. Gen AI-এর অনুরোধ এবং প্রতিক্রিয়া লগ করার জন্য এডিটরে থাকা কোডটি নিচে দেখানো সংস্করণ দিয়ে প্রতিস্থাপন করুন। কোডটি প্রতিস্থাপন করতে, ফাইলটির ভেতরের সমস্ত কন্টেন্ট মুছে ফেলুন এবং তারপর নিচের কোডটি এডিটরে কপি করুন:
    package com.example.demo;
    
    import java.io.IOException;
    import java.util.Collections;
    
    import javax.annotation.PostConstruct;
    import javax.annotation.PreDestroy;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    
    import com.google.cloud.ServiceOptions;
    import com.google.cloud.vertexai.VertexAI;
    import com.google.cloud.vertexai.api.GenerateContentResponse;
    import com.google.cloud.vertexai.generativeai.GenerativeModel;
    import com.google.cloud.vertexai.generativeai.ResponseHandler;
    
    @SpringBootApplication
    public class DemoApplication {
    
        public static void main(String[] args) {
            String port = System.getenv().getOrDefault("PORT", "8080");
            SpringApplication app = new SpringApplication(DemoApplication.class);
            app.setDefaultProperties(Collections.singletonMap("server.port", port));
            app.run(args);
        }
    }
    
    @RestController
    class HelloController {
        private final String projectId = ServiceOptions.getDefaultProjectId();
        private VertexAI vertexAI;
        private GenerativeModel model;
        private final Logger LOGGER = LoggerFactory.getLogger(HelloController.class);
    
        @PostConstruct
        public void init() {
            vertexAI = new VertexAI(projectId, "us-central1");
            model = new GenerativeModel("gemini-1.5-flash", vertexAI);
        }
    
        @PreDestroy
        public void destroy() {
            vertexAI.close();
        }
    
        @GetMapping("/")
        public String getFacts(@RequestParam(defaultValue = "dog") String animal) throws IOException {
            String prompt = "Give me 10 fun facts about " + animal + ". Return this as html without backticks.";
            GenerateContentResponse response = model.generateContent(prompt);
            LOGGER.atInfo()
                    .addKeyValue("animal", animal)
                    .addKeyValue("prompt", prompt)
                    .addKeyValue("response", response)
                    .log("Content is generated");
            return ResponseHandler.getText(response);
        }
    }
    

কয়েক সেকেন্ড পর ক্লাউড শেল এডিটর আপনার পরিবর্তনগুলো স্বয়ংক্রিয়ভাবে সংরক্ষণ করে।

Gen AI অ্যাপ্লিকেশনটির কোড Cloud Run-এ ডেপ্লয় করুন।

  1. টার্মিনাল উইন্ডোতে অ্যাপ্লিকেশনটির সোর্স কোড ক্লাউড রান-এ ডেপ্লয় করার জন্য কমান্ডটি চালান।
    gcloud run deploy codelab-o11y-service \
         --source="${HOME}/codelab-o11y/" \
         --region=us-central1 \
         --allow-unauthenticated
    
    যদি আপনি নিচের মতো একটি প্রম্পট দেখতে পান, যা আপনাকে জানাচ্ছে যে কমান্ডটি একটি নতুন রিপোজিটরি তৈরি করবে, তাহলে Enter চাপুন।
    Deploying from source requires an Artifact Registry Docker repository to store built containers.
    A repository named [cloud-run-source-deploy] in region [us-central1] will be created.
    
    Do you want to continue (Y/n)?
    
    ডেপ্লয়মেন্ট প্রক্রিয়াটিতে কয়েক মিনিট পর্যন্ত সময় লাগতে পারে। ডেপ্লয়মেন্ট প্রক্রিয়াটি সম্পন্ন হওয়ার পর আপনি নিচের মতো আউটপুট দেখতে পাবেন:
    Service [codelab-o11y-service] revision [codelab-o11y-service-00001-t2q] has been deployed and is serving 100 percent of traffic.
    Service URL: https://codelab-o11y-service-12345678901.us-central1.run.app
    
  2. প্রদর্শিত ক্লাউড রান সার্ভিস ইউআরএলটি আপনার ব্রাউজারের একটি আলাদা ট্যাব বা উইন্ডোতে কপি করুন। বিকল্পভাবে, সার্ভিস ইউআরএলটি প্রিন্ট করার জন্য টার্মিনালে নিম্নলিখিত কমান্ডটি চালান এবং ইউআরএলটি খোলার জন্য Ctrl কী চেপে ধরে প্রদর্শিত ইউআরএলটিতে ক্লিক করুন:
    gcloud run services list \
         --format='value(URL)' \
         --filter='SERVICE:"codelab-o11y-service"'
    
    যখন ইউআরএলটি খোলা হবে, তখন আপনি 500 এরর পেতে পারেন অথবা এই মেসেজটি দেখতে পারেন:
    Sorry, this is just a placeholder...
    
    এর মানে হলো, সার্ভিসটির ডেপ্লয়মেন্ট সম্পূর্ণ হয়নি। কিছুক্ষণ অপেক্ষা করুন এবং পেজটি রিফ্রেশ করুন। শেষে আপনি ‘Fun Dog Facts’ দিয়ে শুরু হওয়া একটি লেখা দেখতে পাবেন, যেখানে কুকুর সম্পর্কে ১০টি মজার তথ্য থাকবে।

অ্যাপ্লিকেশন লগ তৈরি করতে সার্ভিস ইউআরএলটি খুলুন। ভিন্ন ভিন্ন ফলাফল পেতে ?animal= প্যারামিটারের মান পরিবর্তন করার সময় পৃষ্ঠাটি রিফ্রেশ করুন।
অ্যাপ্লিকেশন লগগুলো দেখতে নিম্নলিখিত পদক্ষেপগুলো অনুসরণ করুন:

  1. ক্লাউড কনসোলে লগস এক্সপ্লোরার পেজটি খুলতে নিচের বাটনে ক্লিক করুন:

  2. নিম্নলিখিত ফিল্টারটি কোয়েরি প্যানে পেস্ট করুন ( লগ এক্সপ্লোরার ইন্টারফেসের #২):
    LOG_ID("run.googleapis.com%2Fstdout") AND
    severity=DEBUG
    
  3. রান কোয়েরি-তে ক্লিক করুন।

কোয়েরির ফলাফলে নিরাপত্তা রেটিং সহ প্রম্পট এবং ভার্টেক্স এআই প্রতিক্রিয়ার লগগুলো দেখানো হয়।

৯. জেন এআই-এর সাথে মিথস্ক্রিয়া গণনা করুন

ক্লাউড রান পরিচালিত মেট্রিক তৈরি করে যা ডেপ্লয় করা পরিষেবাগুলি নিরীক্ষণ করতে ব্যবহার করা যেতে পারে। ব্যবহারকারী-পরিচালিত মনিটরিং মেট্রিক ডেটা এবং মেট্রিক আপডেটের ফ্রিকোয়েন্সির উপর আরও বেশি নিয়ন্ত্রণ প্রদান করে। এই ধরনের মেট্রিক প্রয়োগ করতে এমন একটি কোড লিখতে হয় যা ডেটা সংগ্রহ করে এবং ক্লাউড মনিটরিং- এ তা লিখে রাখে। ওপেনটেলিমেট্রি এসডিকে ব্যবহার করে এটি প্রয়োগ করার পদ্ধতির জন্য পরবর্তী (ঐচ্ছিক) ধাপটি দেখুন।

এই ধাপে কোডে ইউজার মেট্রিক প্রয়োগ করার একটি বিকল্প দেখানো হয়েছে - লগ-ভিত্তিক মেট্রিক । লগ-ভিত্তিক মেট্রিক আপনাকে সেইসব লগ এন্ট্রি থেকে মনিটরিং মেট্রিক তৈরি করতে দেয়, যা আপনার অ্যাপ্লিকেশন ক্লাউড লগিং-এ লেখে। আমরা পূর্ববর্তী ধাপে প্রয়োগ করা অ্যাপ্লিকেশন লগগুলো ব্যবহার করে ‘কাউন্টার’ টাইপের একটি লগ-ভিত্তিক মেট্রিক নির্ধারণ করব। এই মেট্রিকটি ভার্টেক্স এপিআই-তে সফল কলের সংখ্যা গণনা করবে।

  1. পূর্ববর্তী ধাপে আমরা যে লগস এক্সপ্লোরার উইন্ডোটি ব্যবহার করেছিলাম, সেটির দিকে তাকান। কোয়েরি পেনের অধীনে অ্যাকশনস ড্রপ-ডাউন মেনুটি খুঁজুন এবং এটি খুলতে ক্লিক করুন। মেনুটি খুঁজে পেতে নিচের স্ক্রিনশটটি দেখুন:
    অ্যাকশন ড্রপ-ডাউন মেনু সহ কোয়েরি ফলাফল টুলবার
  2. খোলা মেনু থেকে ' Create metric' নির্বাচন করলে 'Create log-based metric' প্যানেলটি খুলবে।
  3. 'লগ-ভিত্তিক মেট্রিক তৈরি করুন' প্যানেলে একটি নতুন কাউন্টার মেট্রিক কনফিগার করতে এই ধাপগুলো অনুসরণ করুন:
    1. মেট্রিকের ধরণ নির্ধারণ করুন : কাউন্টার নির্বাচন করুন।
    2. Details সেকশনে নিম্নলিখিত ফিল্ডগুলি সেট করুন:
      • লগ মেট্রিকের নাম : নামটি model_interaction_count হিসেবে সেট করুন। নামকরণের ক্ষেত্রে কিছু সীমাবদ্ধতা প্রযোজ্য; বিস্তারিত জানতে ‘নামকরণের সীমাবদ্ধতা সংক্রান্ত সমস্যা সমাধান’ দেখুন।
      • বিবরণ : মেট্রিকটির জন্য একটি বিবরণ লিখুন। উদাহরণস্বরূপ, Number of log entries capturing successful call to model inference.
      • একক : এই স্থানটি খালি রাখুন অথবা 1 অঙ্কটি বসান।
    3. ফিল্টার নির্বাচন বিভাগে মানগুলি অপরিবর্তিত রাখুন। লক্ষ্য করুন যে, বিল্ড ফিল্টার ফিল্ডে সেই একই ফিল্টার রয়েছে যা আমরা অ্যাপ্লিকেশন লগ দেখার জন্য ব্যবহার করেছিলাম।
    4. (ঐচ্ছিক) এমন একটি লেবেল যোগ করুন যা প্রতিটি প্রাণীর জন্য কলের সংখ্যা গণনা করতে সাহায্য করে। দ্রষ্টব্য: এই লেবেলটি মেট্রিকের কার্ডিনালিটি ব্যাপকভাবে বাড়িয়ে দেওয়ার সম্ভাবনা রাখে এবং প্রোডাকশনে ব্যবহারের জন্য এটি সুপারিশ করা হয় না।
      1. লেবেল যোগ করুন -এ ক্লিক করুন।
      2. লেবেল বিভাগে নিম্নলিখিত ক্ষেত্রগুলি সেট করুন:
        • লেবেলের নাম : নামটি animal হিসেবে সেট করুন।
        • বিবরণ : লেবেলটির বিবরণ লিখুন। উদাহরণস্বরূপ, Animal parameter
        • লেবেলের ধরণ : STRING নির্বাচন করুন।
        • ফিল্ডের নাম : টাইপ jsonPayload.animal .
        • রেগুলার এক্সপ্রেশন : এটি খালি রাখুন।
      3. সম্পন্ন ক্লিক করুন
    5. মেট্রিকটি তৈরি করতে 'Create metric'-এ ক্লিক করুন।

আপনি লগ-ভিত্তিক মেট্রিক্স পৃষ্ঠা থেকে, gcloud logging metrics create CLI কমান্ড ব্যবহার করে অথবা google_logging_metric Terraform রিসোর্সের মাধ্যমেও একটি লগ-ভিত্তিক মেট্রিক তৈরি করতে পারেন।

মেট্রিক ডেটা তৈরি করতে সার্ভিস ইউআরএলটি খুলুন। মডেলে একাধিক কল করার জন্য খোলা পেজটি কয়েকবার রিফ্রেশ করুন। আগের মতোই, প্যারামিটারে ভিন্ন ভিন্ন প্রাণী ব্যবহার করার চেষ্টা করুন।

লগ-ভিত্তিক মেট্রিক ডেটা অনুসন্ধান করার জন্য PromQL কোয়েরিটি লিখুন। একটি PromQL কোয়েরি লিখতে, নিম্নলিখিতগুলি করুন:

  1. ক্লাউড কনসোলে মেট্রিক্স এক্সপ্লোরার পেজটি খুলতে নিচের বাটনে ক্লিক করুন:

  2. কোয়েরি-বিল্ডার পেনের টুলবারে, < > MQL অথবা < > PromQL নামের বাটনটি সিলেক্ট করুন। বাটনটির অবস্থান জানতে নিচের ছবিটি দেখুন।
    মেট্রিক্স এক্সপ্লোরারে MQL বাটনের অবস্থান
  3. ল্যাঙ্গুয়েজ টগলে PromQL নির্বাচিত আছে কিনা তা যাচাই করুন। ল্যাঙ্গুয়েজ টগলটি সেই একই টুলবারে রয়েছে, যা আপনাকে আপনার কোয়েরি ফরম্যাট করতে দেয়।
  4. কোয়েরি এডিটরে আপনার কোয়েরিটি লিখুন:
    sum(rate(logging_googleapis_com:user_model_interaction_count{monitored_resource="cloud_run_revision"}[${__interval}]))
    
    PromQL ব্যবহারের বিষয়ে আরও তথ্যের জন্য, ক্লাউড মনিটরিং-এ PromQL দেখুন।
  5. রান কোয়েরি-তে ক্লিক করুন। আপনি এই স্ক্রিনশটের মতো একটি লাইন চার্ট দেখতে পাবেন:
    জিজ্ঞাসিত মেট্রিকগুলি দেখান

    মনে রাখবেন যে, যখন অটো-রান টগলটি সক্রিয় থাকে, তখন রান কোয়েরি বাটনটি দেখানো হয় না।

১০. (ঐচ্ছিক) পর্যবেক্ষণ ও শনাক্তকরণের জন্য ওপেন টেলিমেট্রি ব্যবহার করুন।

পূর্ববর্তী ধাপে যেমন উল্লেখ করা হয়েছে, ওপেনটেলিমেট্রি (Otel) SDK ব্যবহার করে মেট্রিক্স প্রয়োগ করা সম্ভব। মাল্টি-সার্ভিস আর্কিটেকচারে OTel ব্যবহার করা একটি প্রস্তাবিত অনুশীলন। এই ধাপে একটি Spring Boot অ্যাপ্লিকেশনে OTel ইন্সট্রুমেন্টেশন যুক্ত করার পদ্ধতি দেখানো হয়েছে। এই ধাপে আপনি নিম্নলিখিত কাজগুলো করবেন:

  • স্বয়ংক্রিয় ট্রেসিং ক্ষমতা সহ স্প্রিং বুট অ্যাপ্লিকেশন ইন্সট্রুমেন্টেশন
  • সফল মডেল কলের সংখ্যা নিরীক্ষণের জন্য একটি কাউন্টার মেট্রিক বাস্তবায়ন করা
  • অ্যাপ্লিকেশন লগের সাথে ট্রেসিং-এর সম্পর্ক স্থাপন করুন

প্রোডাক্ট-লেভেল সার্ভিসগুলোর জন্য প্রস্তাবিত আর্কিটেকচার হলো একাধিক সার্ভিস থেকে সমস্ত অবজার্ভেবিলিটি ডেটা সংগ্রহ ও ইনজেস্ট করার জন্য OTel কালেক্টর ব্যবহার করা। সরলতার স্বার্থে এই ধাপের কোডটিতে কালেক্টর ব্যবহার করা হয়নি। এর পরিবর্তে, এটি OTel এক্সপোর্ট ব্যবহার করে যা সরাসরি গুগল ক্লাউডে ডেটা লিখে দেয়।

OTel কম্পোনেন্ট এবং অটোমেটিক ট্রেসিং সহ Spring Boot অ্যাপ্লিকেশন সেট আপ করুন

  1. আপনার ব্রাউজারের 'ক্লাউড শেল' উইন্ডোতে (বা ট্যাবে) ফিরে যান।
  2. টার্মিনালে, অতিরিক্ত কনফিগারেশন প্যারামিটার দিয়ে application.permissions ফাইলটি আপডেট করুন:
    cat >> "${HOME}/codelab-o11y/src/main/resources/application.properties" << EOF
    otel.logs.exporter=none
    otel.traces.exporter=google_cloud_trace
    otel.metrics.exporter=google_cloud_monitoring
    otel.resource.attributes.service.name=codelab-o11y-service
    otel.traces.sampler=always_on
    EOF
    
    এই প্যারামিটারগুলো ক্লাউড ট্রেস এবং ক্লাউড মনিটরিং-এ পর্যবেক্ষণযোগ্যতার ডেটা রপ্তানি করাকে সংজ্ঞায়িত করে এবং সমস্ত ট্রেস স্যাম্পলিং করাকে বাধ্যতামূলক করে।
  3. pom.xml ফাইলে প্রয়োজনীয় OpenTelemetry নির্ভরতাগুলো যোগ করুন:
    sed -i 's/<dependencies>/<dependencies>\
    \
            <dependency>\
                <groupId>io.opentelemetry.instrumentation<\/groupId>\
                <artifactId>opentelemetry-spring-boot-starter<\/artifactId>\
            <\/dependency>\
            <dependency>\
                <groupId>com.google.cloud.opentelemetry<\/groupId>\
                <artifactId>exporter-auto<\/artifactId>\
                <version>0.33.0-alpha<\/version>\
            <\/dependency>\
            <dependency>\
                <groupId>com.google.cloud.opentelemetry<\/groupId>\
                <artifactId>exporter-trace<\/artifactId>\
                <version>0.33.0<\/version>\
            <\/dependency>\
            <dependency>\
                <groupId>com.google.cloud.opentelemetry<\/groupId>\
                <artifactId>exporter-metrics<\/artifactId>\
                <version>0.33.0<\/version>\
            <\/dependency>\
    /g' "${HOME}/codelab-o11y/pom.xml"
    
  4. pom.xml ফাইলে OpenTelemetry BOM যোগ করুন:
    sed -i 's/<\/properties>/<\/properties>\
        <dependencyManagement>\
            <dependencies>\
                <dependency>\
                    <groupId>io.opentelemetry.instrumentation<\/groupId>\
                    <artifactId>opentelemetry-instrumentation-bom<\/artifactId>\
                    <version>2.12.0<\/version>\
                    <type>pom<\/type>\
                    <scope>import<\/scope>\
                <\/dependency>\
            <\/dependencies>\
        <\/dependencyManagement>\
    /g' "${HOME}/codelab-o11y/pom.xml"
    
  5. ক্লাউড শেল এডিটরে DemoApplication.java ফাইলটি পুনরায় খুলুন:
    cloudshell edit "${HOME}/codelab-o11y/src/main/java/com/example/demo/DemoApplication.java"
    
  6. বর্তমান কোডটিকে এমন একটি সংস্করণ দিয়ে প্রতিস্থাপন করুন যা পারফরম্যান্স মেট্রিক বৃদ্ধি করে। কোডটি প্রতিস্থাপন করতে, ফাইলটির ভেতরের সমস্ত কন্টেন্ট মুছে ফেলুন এবং তারপর নিচের কোডটি এডিটরে কপি করুন:
    package com.example.demo;
    
    import io.opentelemetry.api.common.AttributeKey;
    import io.opentelemetry.api.common.Attributes;
    import io.opentelemetry.api.OpenTelemetry;
    import io.opentelemetry.api.metrics.LongCounter;
    
    import java.io.IOException;
    import java.util.Collections;
    
    import javax.annotation.PostConstruct;
    import javax.annotation.PreDestroy;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    
    import com.google.cloud.ServiceOptions;
    import com.google.cloud.vertexai.VertexAI;
    import com.google.cloud.vertexai.api.GenerateContentResponse;
    import com.google.cloud.vertexai.generativeai.GenerativeModel;
    import com.google.cloud.vertexai.generativeai.ResponseHandler;
    
    
    @SpringBootApplication
    public class DemoApplication {
    
        public static void main(String[] args) {
            String port = System.getenv().getOrDefault("PORT", "8080");
            SpringApplication app = new SpringApplication(DemoApplication.class);
            app.setDefaultProperties(Collections.singletonMap("server.port", port));
            app.run(args);
        }
    }
    
    @RestController
    class HelloController {
        private final String projectId = ServiceOptions.getDefaultProjectId();
        private VertexAI vertexAI;
        private GenerativeModel model;
        private final Logger LOGGER = LoggerFactory.getLogger(HelloController.class);
        private static final String INSTRUMENTATION_NAME = "genai-o11y/java/workshop/example";
        private static final AttributeKey<String> ANIMAL = AttributeKey.stringKey("animal");
        private final LongCounter counter;
    
        public HelloController(OpenTelemetry openTelemetry) {
            this.counter = openTelemetry.getMeter(INSTRUMENTATION_NAME)
                    .counterBuilder("model_call_counter")
                    .setDescription("Number of successful model calls")
                    .build();
        }
    
        @PostConstruct
        public void init() {
            vertexAI = new VertexAI(projectId, "us-central1");
            model = new GenerativeModel("gemini-1.5-flash", vertexAI);
        }
    
        @PreDestroy
        public void destroy() {
            vertexAI.close();
        }
    
        @GetMapping("/")
        public String getFacts(@RequestParam(defaultValue = "dog") String animal) throws IOException {
            String prompt = "Give me 10 fun facts about " + animal + ". Return this as html without backticks.";
            GenerateContentResponse response = model.generateContent(prompt);
            LOGGER.atInfo()
                    .addKeyValue("animal", animal)
                    .addKeyValue("prompt", prompt)
                    .addKeyValue("response", response)
                    .log("Content is generated");
            counter.add(1, Attributes.of(ANIMAL, animal));
            return ResponseHandler.getText(response);
        }
    }
    
  7. ক্লাউড শেল এডিটরে LoggingEventGoogleCloudEncoder.java ফাইলটি পুনরায় খুলুন:
    cloudshell edit "${HOME}/codelab-o11y/src/main/java/com/example/demo/LoggingEventGoogleCloudEncoder.java"
    
  8. বর্তমান কোডটিকে সেই সংস্করণ দিয়ে প্রতিস্থাপন করুন যা লিখিত লগগুলিতে ট্রেসিং অ্যাট্রিবিউট যোগ করে। অ্যাট্রিবিউটগুলি যোগ করার ফলে লগগুলিকে সঠিক ট্রেস স্প্যানের সাথে সম্পর্কযুক্ত করা সম্ভব হয়। কোডটি প্রতিস্থাপন করতে, ফাইলটির সমস্ত কন্টেন্ট মুছে ফেলুন এবং তারপর নিচের কোডটি এডিটরে কপি করুন:
    package com.example.demo;
    
    import static ch.qos.logback.core.CoreConstants.UTF_8_CHARSET;
    
    import java.time.Instant;
    import java.util.HashMap;
    
    import ch.qos.logback.core.encoder.EncoderBase;
    import ch.qos.logback.classic.Level;
    import ch.qos.logback.classic.spi.ILoggingEvent;
    import com.google.cloud.ServiceOptions;
    import io.opentelemetry.api.trace.Span;
    import io.opentelemetry.api.trace.SpanContext;
    import io.opentelemetry.context.Context;
    
    import com.google.gson.Gson;
    
    
    public class LoggingEventGoogleCloudEncoder extends EncoderBase<ILoggingEvent>  {
        private static final byte[] EMPTY_BYTES = new byte[0];
        private final Gson gson;
        private final String projectId;
        private final String tracePrefix;
    
    
        public LoggingEventGoogleCloudEncoder() {
            this.gson = new Gson();
            this.projectId = lookUpProjectId();
            this.tracePrefix = "projects/" + (projectId == null ? "" : projectId) + "/traces/";
        }
    
        private static String lookUpProjectId() {
            return ServiceOptions.getDefaultProjectId();
        }
    
        @Override
        public byte[] headerBytes() {
            return EMPTY_BYTES;
        }
    
        @Override
        public byte[] encode(ILoggingEvent e) {
            var timestamp = Instant.ofEpochMilli(e.getTimeStamp());
            var fields = new HashMap<String, Object>() {
                {
                    put("timestamp", timestamp.toString());
                    put("severity", severityFor(e.getLevel()));
                    put("message", e.getMessage());
                    SpanContext context = Span.fromContext(Context.current()).getSpanContext();
                    if (context.isValid()) {
                        put("logging.googleapis.com/trace", tracePrefix + context.getTraceId());
                        put("logging.googleapis.com/spanId", context.getSpanId());
                        put("logging.googleapis.com/trace_sampled", Boolean.toString(context.isSampled()));
                    }
                }
            };
            var params = e.getKeyValuePairs();
            if (params != null && params.size() > 0) {
                params.forEach(kv -> fields.putIfAbsent(kv.key, kv.value));
            }
            var data = gson.toJson(fields) + "\n";
            return data.getBytes(UTF_8_CHARSET);
        }
    
        @Override
        public byte[] footerBytes() {
            return EMPTY_BYTES;
        }
    
        private static String severityFor(Level level) {
            switch (level.toInt()) {
                case Level.TRACE_INT:
                return "DEBUG";
                case Level.DEBUG_INT:
                return "DEBUG";
                case Level.INFO_INT:
                return "INFO";
                case Level.WARN_INT:
                return "WARNING";
                case Level.ERROR_INT:
                return "ERROR";
                default:
                return "DEFAULT";
            }
        }
    }
    

কয়েক সেকেন্ড পর ক্লাউড শেল এডিটর আপনার পরিবর্তনগুলো স্বয়ংক্রিয়ভাবে সংরক্ষণ করে।

Gen AI অ্যাপ্লিকেশনটির কোড Cloud Run-এ ডেপ্লয় করুন।

  1. টার্মিনাল উইন্ডোতে অ্যাপ্লিকেশনটির সোর্স কোড ক্লাউড রান-এ ডেপ্লয় করার জন্য কমান্ডটি চালান।
    gcloud run deploy codelab-o11y-service \
         --source="${HOME}/codelab-o11y/" \
         --region=us-central1 \
         --allow-unauthenticated
    
    যদি আপনি নিচের মতো একটি প্রম্পট দেখতে পান, যা আপনাকে জানাচ্ছে যে কমান্ডটি একটি নতুন রিপোজিটরি তৈরি করবে, তাহলে Enter চাপুন।
    Deploying from source requires an Artifact Registry Docker repository to store built containers.
    A repository named [cloud-run-source-deploy] in region [us-central1] will be created.
    
    Do you want to continue (Y/n)?
    
    ডেপ্লয়মেন্ট প্রক্রিয়াটিতে কয়েক মিনিট পর্যন্ত সময় লাগতে পারে। ডেপ্লয়মেন্ট প্রক্রিয়াটি সম্পন্ন হওয়ার পর আপনি নিচের মতো আউটপুট দেখতে পাবেন:
    Service [codelab-o11y-service] revision [codelab-o11y-service-00001-t2q] has been deployed and is serving 100 percent of traffic.
    Service URL: https://codelab-o11y-service-12345678901.us-central1.run.app
    
  2. প্রদর্শিত ক্লাউড রান সার্ভিস ইউআরএলটি আপনার ব্রাউজারের একটি আলাদা ট্যাব বা উইন্ডোতে কপি করুন। বিকল্পভাবে, সার্ভিস ইউআরএলটি প্রিন্ট করার জন্য টার্মিনালে নিম্নলিখিত কমান্ডটি চালান এবং ইউআরএলটি খোলার জন্য Ctrl কী চেপে ধরে প্রদর্শিত ইউআরএলটিতে ক্লিক করুন:
    gcloud run services list \
         --format='value(URL)' \
         --filter='SERVICE:"codelab-o11y-service"'
    
    যখন ইউআরএলটি খোলা হবে, তখন আপনি 500 এরর পেতে পারেন অথবা এই মেসেজটি দেখতে পারেন:
    Sorry, this is just a placeholder...
    
    এর মানে হলো, সার্ভিসটির ডেপ্লয়মেন্ট সম্পূর্ণ হয়নি। কিছুক্ষণ অপেক্ষা করুন এবং পেজটি রিফ্রেশ করুন। শেষে আপনি ‘Fun Dog Facts’ দিয়ে শুরু হওয়া একটি লেখা দেখতে পাবেন, যেখানে কুকুর সম্পর্কে ১০টি মজার তথ্য থাকবে।

টেলিমেট্রি ডেটা তৈরি করতে সার্ভিস ইউআরএলটি খুলুন। ভিন্ন ভিন্ন ফলাফল পেতে ?animal= প্যারামিটারের মান পরিবর্তন করার সময় পেজটি রিফ্রেশ করুন।

অ্যাপ্লিকেশন ট্রেস অন্বেষণ করুন

  1. ক্লাউড কনসোলে ট্রেস এক্সপ্লোরার পেজটি খুলতে নিচের বাটনে ক্লিক করুন:

  2. সবচেয়ে সাম্প্রতিক ট্রেসগুলোর মধ্যে একটি নির্বাচন করুন। আপনি নিচের স্ক্রিনশটের মতো ৫ বা ৬টি স্প্যান দেখতে পাবেন।
    ট্রেস এক্সপ্লোরারে অ্যাপ স্প্যানের দৃশ্য
  3. সেই স্প্যানটি খুঁজুন যা ইভেন্ট হ্যান্ডলার ( fun_facts মেথড)-এর কলটি ট্রেস করে। এটি হবে / নামের শেষ স্প্যানটি।
  4. ট্রেস ডিটেইলস প্যানে 'লগস অ্যান্ড ইভেন্টস' নির্বাচন করুন। আপনি এই নির্দিষ্ট স্প্যানটির সাথে সম্পর্কিত অ্যাপ্লিকেশন লগগুলো দেখতে পাবেন। ট্রেস এবং লগে থাকা ট্রেস ও স্প্যান আইডি ব্যবহার করে এই সম্পর্কটি শনাক্ত করা হয়। আপনার সেই অ্যাপ্লিকেশন লগটি দেখার কথা, যেটি ভার্টেক্স এপিআই-এর প্রম্পট এবং রেসপন্স লিখেছিল।

কাউন্টার মেট্রিক অন্বেষণ করুন

  1. ক্লাউড কনসোলে মেট্রিক্স এক্সপ্লোরার পেজটি খুলতে নিচের বাটনে ক্লিক করুন:

  2. কোয়েরি-বিল্ডার পেনের টুলবারে, < > MQL অথবা < > PromQL নামের বাটনটি সিলেক্ট করুন। বাটনটির অবস্থান জানতে নিচের ছবিটি দেখুন।
    মেট্রিক্স এক্সপ্লোরারে MQL বাটনের অবস্থান
  3. ল্যাঙ্গুয়েজ টগলে PromQL নির্বাচিত আছে কিনা তা যাচাই করুন। ল্যাঙ্গুয়েজ টগলটি সেই একই টুলবারে রয়েছে, যা আপনাকে আপনার কোয়েরি ফরম্যাট করতে দেয়।
  4. কোয়েরি এডিটরে আপনার কোয়েরিটি লিখুন:
    sum(rate(workload_googleapis_com:model_call_counter{monitored_resource="generic_task"}[${__interval}]))
    
  5. রান কোয়েরি-তে ক্লিক করুন। যখন অটো-রান টগলটি সক্রিয় থাকে, তখন রান কোয়েরি বাটনটি দেখানো হয় না।

১১. (ঐচ্ছিক) লগ থেকে সংবেদনশীল তথ্য গোপন করা

ধাপ ১০-এ আমরা জেমিনি মডেলের সাথে অ্যাপ্লিকেশনটির মিথস্ক্রিয়া সম্পর্কিত তথ্য লগ করেছি। এই তথ্যের মধ্যে প্রাণীটির নাম, প্রকৃত প্রম্পট এবং মডেলটির প্রতিক্রিয়া অন্তর্ভুক্ত ছিল। যদিও লগে এই তথ্য সংরক্ষণ করা নিরাপদ হওয়া উচিত, তবে অন্যান্য অনেক ক্ষেত্রে এটি সবসময় সত্যি নাও হতে পারে। প্রম্পটটিতে কিছু ব্যক্তিগত বা অন্য কোনো সংবেদনশীল তথ্য থাকতে পারে যা একজন ব্যবহারকারী সংরক্ষণ করতে চান না। এর সমাধান করতে, আপনি ক্লাউড লগিং-এ লেখা সংবেদনশীল ডেটা অস্পষ্ট (obfuscate) করতে পারেন। কোডের পরিবর্তন ন্যূনতম রাখতে নিম্নলিখিত সমাধানটি সুপারিশ করা হচ্ছে।

  1. আগত লগ এন্ট্রিগুলি সংরক্ষণ করার জন্য একটি পাবসাব টপিক তৈরি করুন।
  2. একটি লগ সিঙ্ক তৈরি করুন যা গৃহীত লগগুলিকে PubSub টপিকে পুনঃনির্দেশিত করে।
  3. নিম্নলিখিত ধাপগুলি অনুসরণ করে একটি ডেটাফ্লো পাইপলাইন তৈরি করুন যা PubSub টপিকে পুনঃনির্দেশিত লগগুলি পরিবর্তন করে:
    1. PubSub টপিক থেকে একটি লগ এন্ট্রি পড়ুন
    2. DLP ইন্সপেকশন API ব্যবহার করে এন্ট্রির পেলোডে সংবেদনশীল তথ্য আছে কিনা তা পরীক্ষা করুন।
    3. ডিএলপি রিডাকশন পদ্ধতিগুলোর মধ্যে যেকোনো একটি ব্যবহার করে পেলোডের সংবেদনশীল তথ্য গোপন করুন।
    4. অস্পষ্ট লগ এন্ট্রিটি ক্লাউড লগিং-এ লিখুন।
  4. পাইপলাইনটি স্থাপন করুন

১২. (ঐচ্ছিক) পরিষ্কার করা

কোডল্যাবে ব্যবহৃত রিসোর্স এবং এপিআই-এর জন্য চার্জ হওয়ার ঝুঁকি এড়াতে, ল্যাব শেষ করার পর প্রজেক্টটি পরিষ্কার করে ফেলার পরামর্শ দেওয়া হয়। বিলিং বন্ধ করার সবচেয়ে সহজ উপায় হলো কোডল্যাবের জন্য তৈরি করা প্রজেক্টটি ডিলিট করে দেওয়া।

  1. প্রজেক্টটি ডিলিট করতে টার্মিনালে `delete project` কমান্ডটি চালান:
    PROJECT_ID=$(gcloud config get-value project)
    gcloud projects delete ${PROJECT_ID} --quiet
    
    আপনার ক্লাউড প্রজেক্ট মুছে ফেললে সেই প্রজেক্টে ব্যবহৃত সমস্ত রিসোর্স এবং এপিআই-এর বিলিং বন্ধ হয়ে যাবে। আপনি এই বার্তাটি দেখতে পাবেন, যেখানে PROJECT_ID হবে আপনার প্রজেক্ট আইডি:
    Deleted [https://cloudresourcemanager.googleapis.com/v1/projects/PROJECT_ID].
    
    You can undo this operation for a limited period by running the command below.
        $ gcloud projects undelete PROJECT_ID
    
    See https://cloud.google.com/resource-manager/docs/creating-managing-projects for information on shutting down projects.
    
  2. (ঐচ্ছিক) যদি কোনো ত্রুটি দেখা দেয়, তাহলে ল্যাবের সময় ব্যবহৃত প্রজেক্ট আইডিটি খুঁজে বের করতে ধাপ ৫ দেখুন। প্রথম নির্দেশনার কমান্ডে এটি প্রতিস্থাপন করুন। উদাহরণস্বরূপ, যদি আপনার প্রজেক্ট আইডি lab-example-project হয়, তাহলে কমান্ডটি হবে:
    gcloud projects delete lab-project-id-example --quiet
    

১৩. অভিনন্দন

এই ল্যাবে, আপনি একটি Gen AI অ্যাপ্লিকেশন তৈরি করেছেন যা পূর্বাভাস দেওয়ার জন্য Gemini মডেল ব্যবহার করে। এবং অ্যাপ্লিকেশনটিকে প্রয়োজনীয় মনিটরিং ও লগিং সক্ষমতা দিয়ে সজ্জিত করেছেন। আপনি সোর্স কোড থেকে অ্যাপ্লিকেশনটি এবং এর পরিবর্তনগুলো Cloud Run- এ ডেপ্লয় করেছেন। এরপর, অ্যাপ্লিকেশনটির নির্ভরযোগ্যতা সম্পর্কে নিশ্চিত হওয়ার জন্য আপনি এর পারফরম্যান্স ট্র্যাক করতে Google Cloud Observability প্রোডাক্টগুলো ব্যবহার করেছেন।

আপনি বর্তমানে যে পণ্যগুলো নিয়ে কাজ করছেন সেগুলোর উন্নতির জন্য কোনো ইউজার এক্সপেরিয়েন্স (UX) গবেষণা সমীক্ষায় অন্তর্ভুক্ত হতে আগ্রহী হলে, এখানে নিবন্ধন করুন

আপনার পড়াশোনা চালিয়ে যাওয়ার জন্য এখানে কিছু উপায় দেওয়া হলো: