So observability , signals play a central role 
→ it’s the intel we’re basing our decisions on oky , 

Any system under obserbvability emits some signals , 
These signals can be used to understand the system and make decisions to influence it 


Q- m3nha el signal howma all “singnal” el system y emit fihom y5alik tnjm 
T3rf el state mt3o and tnjm t3ml influence 3lih (proactive or reactive oky ) 


→ donc in terms of signals (and sources) we can differentialte betwenn two cases : 

Source , such as code, that you own and can instrument yourself (that is , decide where and what kind of signals to emit ) 
Sources you don’t own , meaning any signals will be predefined , Your task is limited to selecting which signals to consume , 
* — code that is a dependency of your code (library ,package , module , etc..) 
— The component’s source code is not available (eg a binary file ) 
– the component only offers a (networked ) api , any managed service from your cloud provider of choice falls into this category oky 


→ no matter you own or do not own you the code , you need to collect these signals and send them to a central palace for processing and storage , 
This what we call the “Telemetry part “ 


→ also in to think in term of “(ROI) not only you need to understand this singls but also understznd the cost of they 

In the context of observability, signals play a central role: this is the intel we’re basing our decisions on. On a high level, we can differentiate between signals numerical in nature (e.g., the number of service invocations) and signals that carry textual payload that requires human interpretation (e.g., a log line). As discussed in chapter 1, the system under observation, or just system (e.g., a Kubernetes application or a serverless app based on Lambda functions), emits signals from various sources. You, as a human, or equally a piece of software, then use these signals to understand the system and make decisions to influence it. There is a one-to-many relation between the system and sources. Your system typically involves compute, storage, and network, each of these representing a signal source. We will cover the sources in detail in chapter 3. This chapter covers  What different signal types are  When and how to use a certain signal type  The costs and benefits of each signal type  How to figure out which signals are relevant  Determining signal baselines 2.1 Reference example 15 In terms of signals (and sources), we can differentiate between two cases:  Sources, such as code, that you own and can instrument yourself (that is, decide where and what kind of signals to emit).  Sources you don’t own, meaning any signals will be predefined. Your task is limited to selecting which signals to consume, in this case. This might be due to several reasons: – Code that is a dependency of your code (library, package, module, etc.). – The component’s source code is not available (e.g., a binary file). – The component only offers a (networked) API. Any managed service from your cloud provider of choice falls into this category. No matter whether you own the code and can decide what signal types to emit or are working with a component you don’t own, at some point in time, you want to collect the signals and send them to a central place for processing and storage. This is the telemetry part. With observability, you want to take an approach driven by return on investment (ROI). In other words, you not only need to understand the different signals available but also the costs of each signal type and what they enable you to do. In this chapter, we will review the most common signal types, examine how to instrument and collect each, and discuss the costs and benefits of doing so

Q- so let’s take an hands on approch here oky 
  Let’s say my operational application use microsrices architeture oky 

With a product , order , inventory service oky 
(the stack is java spring ecosutem oky ) 

Q- first tell implement a minilste crud application for each service oky here7
Sure! Let's take a hands-on approach to building a mini CRUD (Create, Read, Update, Delete) application for each of your microservices: Product, Order, and Inventory using the Java Spring Boot ecosystem. We'll outline each service with essential components to get you started.
Overview
Each microservice will have the following components:
Entity: Represents the data model.
Repository: Interfaces with the database.
Service: Contains business logic.
Controller: Handles HTTP requests.
DTOs (Data Transfer Objects): Facilitates data exchange between layers.
To keep things simple, we'll use Spring Boot with Spring Data JPA and an in-memory H2 database for each service.
Prerequisites
Java 17 or higher
Maven or Gradle
IDE like IntelliJ IDEA or Eclipse
1. Product Service
Step 1: Initialize Spring Boot Project
You can use Spring Initializr to generate the project with the following dependencies:
Spring Web
Spring Data JPA
H2 Database
Lombok (optional, for reducing boilerplate code)
Step 2: Define the Product Entity
// src/main/java/com/example/productservice/entity/Product.java
package com.example.productservice.entity;

import jakarta.persistence.*;
import lombok.*;

@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Product {
  
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
  
    private String name;
  
    private String description;
  
    private Double price;
  
    private Integer quantity;
}


Step 3: Create the Repository
// src/main/java/com/example/productservice/repository/ProductRepository.java
package com.example.productservice.repository;

import com.example.productservice.entity.Product;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface ProductRepository extends JpaRepository<Product, Long> {
}


Step 4: Implement the Service
// src/main/java/com/example/productservice/service/ProductService.java
package com.example.productservice.service;

import com.example.productservice.entity.Product;
import com.example.productservice.repository.ProductRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;

@Service
public class ProductService {
  
    @Autowired
    private ProductRepository productRepository;
  
    public Product createProduct(Product product) {
        return productRepository.save(product);
    }
  
    public List<Product> getAllProducts() {
        return productRepository.findAll();
    }
  
    public Optional<Product> getProductById(Long id) {
        return productRepository.findById(id);
    }
  
    public Product updateProduct(Long id, Product productDetails) {
        Product product = productRepository.findById(id)
            .orElseThrow(() -> new RuntimeException("Product not found"));
      
        product.setName(productDetails.getName());
        product.setDescription(productDetails.getDescription());
        product.setPrice(productDetails.getPrice());
        product.setQuantity(productDetails.getQuantity());
      
        return productRepository.save(product);
    }
  
    public void deleteProduct(Long id) {
        Product product = productRepository.findById(id)
            .orElseThrow(() -> new RuntimeException("Product not found"));
        productRepository.delete(product);
    }
}


Step 5: Create the Controller
// src/main/java/com/example/productservice/controller/ProductController.java
package com.example.productservice.controller;

import com.example.productservice.entity.Product;
import com.example.productservice.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;

@RestController
@RequestMapping("/api/products")
public class ProductController {
  
    @Autowired
    private ProductService productService;
  
    @PostMapping
    public Product createProduct(@RequestBody Product product) {
        return productService.createProduct(product);
    }
  
    @GetMapping
    public List<Product> getAllProducts() {
        return productService.getAllProducts();
    }
  
    @GetMapping("/{id}")
    public ResponseEntity<Product> getProductById(@PathVariable Long id) {
        return productService.getProductById(id)
            .map(ResponseEntity::ok)
            .orElse(ResponseEntity.notFound().build());
    }
  
    @PutMapping("/{id}")
    public ResponseEntity<Product> updateProduct(@PathVariable Long id, @RequestBody Product productDetails) {
        try {
            Product updatedProduct = productService.updateProduct(id, productDetails);
            return ResponseEntity.ok(updatedProduct);
        } catch (RuntimeException e) {
            return ResponseEntity.notFound().build();
        }
    }
  
    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deleteProduct(@PathVariable Long id) {
        try {
            productService.deleteProduct(id);
            return ResponseEntity.noContent().build();
        } catch (RuntimeException e) {
            return ResponseEntity.notFound().build();
        }
    }
}


Step 6: Configure Application Properties
# src/main/resources/application.properties
spring.datasource.url=jdbc:h2:mem:productsdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.h2.console.enabled=true
spring.jpa.hibernate.ddl-auto=update
server.port=8081


Step 7: Run the Application
Execute the main method in ProductServiceApplication.java or use Maven/Gradle commands:
mvn spring-boot:run


Your Product Service will be accessible at http://localhost:8081/api/products.
2. Order Service
Follow similar steps to create the Order Service.
Step 1: Initialize Spring Boot Project
Include dependencies:
Spring Web
Spring Data JPA
H2 Database
Lombok
Step 2: Define the Order Entity
// src/main/java/com/example/orderservice/entity/Order.java
package com.example.orderservice.entity;

import jakarta.persistence.*;
import lombok.*;

import java.util.List;

@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Table(name = "orders") // 'order' may be a reserved keyword
public class Order {
  
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
  
    private Long productId;
  
    private Integer quantity;
  
    private Double totalPrice;
  
    // Additional fields like customer details can be added here
}


Step 3: Create the Repository
// src/main/java/com/example/orderservice/repository/OrderRepository.java
package com.example.orderservice.repository;

import com.example.orderservice.entity.Order;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface OrderRepository extends JpaRepository<Order, Long> {
}


Step 4: Implement the Service
// src/main/java/com/example/orderservice/service/OrderService.java
package com.example.orderservice.service;

import com.example.orderservice.entity.Order;
import com.example.orderservice.repository.OrderRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;

@Service
public class OrderService {
  
    @Autowired
    private OrderRepository orderRepository;
  
    public Order createOrder(Order order) {
        return orderRepository.save(order);
    }
  
    public List<Order> getAllOrders() {
        return orderRepository.findAll();
    }
  
    public Optional<Order> getOrderById(Long id) {
        return orderRepository.findById(id);
    }
  
    public Order updateOrder(Long id, Order orderDetails) {
        Order order = orderRepository.findById(id)
            .orElseThrow(() -> new RuntimeException("Order not found"));
      
        order.setProductId(orderDetails.getProductId());
        order.setQuantity(orderDetails.getQuantity());
        order.setTotalPrice(orderDetails.getTotalPrice());
      
        return orderRepository.save(order);
    }
  
    public void deleteOrder(Long id) {
        Order order = orderRepository.findById(id)
            .orElseThrow(() -> new RuntimeException("Order not found"));
        orderRepository.delete(order);
    }
}


Step 5: Create the Controller
// src/main/java/com/example/orderservice/controller/OrderController.java
package com.example.orderservice.controller;

import com.example.orderservice.entity.Order;
import com.example.orderservice.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;

@RestController
@RequestMapping("/api/orders")
public class OrderController {
  
    @Autowired
    private OrderService orderService;
  
    @PostMapping
    public Order createOrder(@RequestBody Order order) {
        return orderService.createOrder(order);
    }
  
    @GetMapping
    public List<Order> getAllOrders() {
        return orderService.getAllOrders();
    }
  
    @GetMapping("/{id}")
    public ResponseEntity<Order> getOrderById(@PathVariable Long id) {
        return orderService.getOrderById(id)
            .map(ResponseEntity::ok)
            .orElse(ResponseEntity.notFound().build());
    }
  
    @PutMapping("/{id}")
    public ResponseEntity<Order> updateOrder(@PathVariable Long id, @RequestBody Order orderDetails) {
        try {
            Order updatedOrder = orderService.updateOrder(id, orderDetails);
            return ResponseEntity.ok(updatedOrder);
        } catch (RuntimeException e) {
            return ResponseEntity.notFound().build();
        }
    }
  
    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deleteOrder(@PathVariable Long id) {
        try {
            orderService.deleteOrder(id);
            return ResponseEntity.noContent().build();
        } catch (RuntimeException e) {
            return ResponseEntity.notFound().build();
        }
    }
}


Step 6: Configure Application Properties
# src/main/resources/application.properties
spring.datasource.url=jdbc:h2:mem:ordersdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.h2.console.enabled=true
spring.jpa.hibernate.ddl-auto=update
server.port=8082


Step 7: Run the Application
Execute the main method in OrderServiceApplication.java or use Maven/Gradle commands:
mvn spring-boot:run


Your Order Service will be accessible at http://localhost:8082/api/orders.
3. Inventory Service
Similarly, create the Inventory Service.
Step 1: Initialize Spring Boot Project
Include dependencies:
Spring Web
Spring Data JPA
H2 Database
Lombok
Step 2: Define the Inventory Entity
// src/main/java/com/example/inventoryservice/entity/Inventory.java
package com.example.inventoryservice.entity;

import jakarta.persistence.*;
import lombok.*;

@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Inventory {
  
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
  
    private Long productId;
  
    private Integer availableQuantity;
  
    private String location;
}


Step 3: Create the Repository
// src/main/java/com/example/inventoryservice/repository/InventoryRepository.java
package com.example.inventoryservice.repository;

import com.example.inventoryservice.entity.Inventory;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface InventoryRepository extends JpaRepository<Inventory, Long> {
}


Step 4: Implement the Service
// src/main/java/com/example/inventoryservice/service/InventoryService.java
package com.example.inventoryservice.service;

import com.example.inventoryservice.entity.Inventory;
import com.example.inventoryservice.repository.InventoryRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;

@Service
public class InventoryService {
  
    @Autowired
    private InventoryRepository inventoryRepository;
  
    public Inventory createInventory(Inventory inventory) {
        return inventoryRepository.save(inventory);
    }
  
    public List<Inventory> getAllInventories() {
        return inventoryRepository.findAll();
    }
  
    public Optional<Inventory> getInventoryById(Long id) {
        return inventoryRepository.findById(id);
    }
  
    public Inventory updateInventory(Long id, Inventory inventoryDetails) {
        Inventory inventory = inventoryRepository.findById(id)
            .orElseThrow(() -> new RuntimeException("Inventory not found"));
      
        inventory.setProductId(inventoryDetails.getProductId());
        inventory.setAvailableQuantity(inventoryDetails.getAvailableQuantity());
        inventory.setLocation(inventoryDetails.getLocation());
      
        return inventoryRepository.save(inventory);
    }
  
    public void deleteInventory(Long id) {
        Inventory inventory = inventoryRepository.findById(id)
            .orElseThrow(() -> new RuntimeException("Inventory not found"));
        inventoryRepository.delete(inventory);
    }
}


Step 5: Create the Controller
// src/main/java/com/example/inventoryservice/controller/InventoryController.java
package com.example.inventoryservice.controller;

import com.example.inventoryservice.entity.Inventory;
import com.example.inventoryservice.service.InventoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;

@RestController
@RequestMapping("/api/inventories")
public class InventoryController {
  
    @Autowired
    private InventoryService inventoryService;
  
    @PostMapping
    public Inventory createInventory(@RequestBody Inventory inventory) {
        return inventoryService.createInventory(inventory);
    }
  
    @GetMapping
    public List<Inventory> getAllInventories() {
        return inventoryService.getAllInventories();
    }
  
    @GetMapping("/{id}")
    public ResponseEntity<Inventory> getInventoryById(@PathVariable Long id) {
        return inventoryService.getInventoryById(id)
            .map(ResponseEntity::ok)
            .orElse(ResponseEntity.notFound().build());
    }
  
    @PutMapping("/{id}")
    public ResponseEntity<Inventory> updateInventory(@PathVariable Long id, @RequestBody Inventory inventoryDetails) {
        try {
            Inventory updatedInventory = inventoryService.updateInventory(id, inventoryDetails);
            return ResponseEntity.ok(updatedInventory);
        } catch (RuntimeException e) {
            return ResponseEntity.notFound().build();
        }
    }
  
    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deleteInventory(@PathVariable Long id) {
        try {
            inventoryService.deleteInventory(id);
            return ResponseEntity.noContent().build();
        } catch (RuntimeException e) {
            return ResponseEntity.notFound().build();
        }
    }
}


Step 6: Configure Application Properties
# src/main/resources/application.properties
spring.datasource.url=jdbc:h2:mem:inventorydb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.h2.console.enabled=true
spring.jpa.hibernate.ddl-auto=update
server.port=8083


Step 7: Run the Application
Execute the main method in InventoryServiceApplication.java or use Maven/Gradle commands:
mvn spring-boot:run


Your Inventory Service will be accessible at http://localhost:8083/api/inventories.
Testing the Microservices
You can use tools like Postman or cURL to test the CRUD operations.
Example: Testing the Product Service
Create a Product
curl -X POST http://localhost:8081/api/products \
-H "Content-Type: application/json" \
-d '{
      "name": "Laptop",
      "description": "A high-end gaming laptop",
      "price": 1500.00,
      "quantity": 10
    }'


Get All Products
curl http://localhost:8081/api/products


Get Product by ID
curl http://localhost:8081/api/products/1


Update Product
curl -X PUT http://localhost:8081/api/products/1 \
-H "Content-Type: application/json" \
-d '{
      "name": "Laptop Pro",
      "description": "An upgraded high-end gaming laptop",
      "price": 1800.00,
      "quantity": 5
    }'


Delete Product
curl -X DELETE http://localhost:8081/api/products/1


Repeat similar steps for Order and Inventory services using their respective ports (8082 for Order and 8083 for Inventory).
Next Steps
Inter-Service Communication: Implement communication between microservices using REST APIs, Feign Clients, or gRPC.
Database Configuration: Move from in-memory H2 databases to persistent databases like PostgreSQL or MySQL.
Containerization: Dockerize each microservice for easier deployment.
Orchestration: Use Kubernetes for orchestrating your microservices.
Observability: Integrate monitoring, logging, and tracing tools to enhance observability. Tools like Prometheus, Grafana, ELK Stack, and Jaeger are popular choices.
Summary
You've now set up three basic CRUD microservices using Java Spring Boot:
Product Service on port 8081
Order Service on port 8082
Inventory Service on port 8083
Each service includes endpoints to Create, Read, Update, and Delete resources. This foundation allows you to build upon with more complex features, inter-service communication, and observability integrations as you progress.
Feel free to ask if you need further assistance with any of the steps or additional features!

Q- let’s say we build this serice and run theire datase also (using docker-compose for this paty) 


Q- now i want to understand the concept of signals 
That we have already discusion in the start of the notes , oky 
Q- ally all the notion in action for our project oky 

Q-using a question & answer style oky