diff --git a/README.md b/README.md
index 4057c7673434fe2fc683e412a3187d52c66d3f5e..8d131ff2be2f455da1a0b88ee639e8057a34a78d 100644
--- a/README.md
+++ b/README.md
@@ -85,17 +85,42 @@ ENV SPRING_PROFILES_ACTIVE docker,mysql
 In the `mysql section` of the `application.yml` from the [Configuration repository], you have to change 
 the host and port of your MySQL JDBC connection string. 
 
+## Custom metrics monitoring
+
+@todo Add default custom dashboards to grafana
+
+Grafana and Prometheus are included in the `docker-compose.yml` configuration, and the public facing applications have been instrumented with [MicroMeter](https://micrometer.io) to collect JVM and custom business metrics.
+
+### Using Prometheus
+
+* Prometheus can be accessed from your local machine at http://localhost:9091
+
+### Using Grafana with Prometheus
+
+* Login to Grafana at http://localhost:3000, the default user/pass is `admin:admin`, you will be prompted to change your password.
+* Setup a prometheus datasource and point the URL to `http://prometheus-server:9090`, leave all the other options set to their default.
+* Add the [Micrometer/SpringBoot dashboard](https://grafana.com/dashboards/4701) via the Import Dashboard menu item. The id for the dashboard is `4701` 
+
+### Custom metrics implementation
+
+* `customers-service` application has the following custom metrics enabled:
+  * counter: `create.owner`
+  * counter: `update.owner`
+  * counter: `create.pet`
+  * counter: `update.pet`
+* `visits-service` application has the following custom metrics enabled:
+  * counter: `create.visit`
 
 ## Looking for something in particular?
 
-| Spring Cloud components | Resources  |
-|-------------------------|------------|
-| Configuration server    | [Config server properties](spring-petclinic-config-server/src/main/resources/application.yml) and [Configuration repository] |
-| Service Discovery       | [Eureka server](spring-petclinic-discovery-server) and [Service discovery client](spring-petclinic-vets-service/src/main/java/org/springframework/samples/petclinic/vets/VetsServiceApplication.java) |
-| API Gateway             | [Zuul reverse proxy](spring-petclinic-api-gateway/src/main/java/org/springframework/samples/petclinic/api/ApiGatewayApplication.java) and [Routing configuration](https://github.com/spring-petclinic/spring-petclinic-microservices-config/blob/master/api-gateway.yml) |
-| Docker Compose          | [Spring Boot with Docker guide](https://spring.io/guides/gs/spring-boot-docker/) and [docker-compose file](docker-compose.yml) |
-| Circuit Breaker         | [Circuit Breaker with Hystrix guide](https://spring.io/guides/gs/circuit-breaker/) and [fallback method configuration](spring-petclinic-api-gateway/src/main/java/org/springframework/samples/petclinic/api/application/VisitsServiceClient.java) |
-| Graphite Monitoring     | TBD |
+| Spring Cloud components         | Resources  |
+|---------------------------------|------------|
+| Configuration server            | [Config server properties](spring-petclinic-config-server/src/main/resources/application.yml) and [Configuration repository] |
+| Service Discovery               | [Eureka server](spring-petclinic-discovery-server) and [Service discovery client](spring-petclinic-vets-service/src/main/java/org/springframework/samples/petclinic/vets/VetsServiceApplication.java) |
+| API Gateway                     | [Zuul reverse proxy](spring-petclinic-api-gateway/src/main/java/org/springframework/samples/petclinic/api/ApiGatewayApplication.java) and [Routing configuration](https://github.com/spring-petclinic/spring-petclinic-microservices-config/blob/master/api-gateway.yml) |
+| Docker Compose                  | [Spring Boot with Docker guide](https://spring.io/guides/gs/spring-boot-docker/) and [docker-compose file](docker-compose.yml) |
+| Circuit Breaker                 | TBD |
+| Grafana / Prometheus Monitoring | [Micrometer implementation](https://micrometer.io/) |
 
  Front-end module  | Files |
 |-------------------|-------|
diff --git a/docker-compose.yml b/docker-compose.yml
index 50efcee448ecb95d530bdf6b153d6b5e9eb05b5a..1209bd7b4d87be0ae1cdc76d3e077193e021aa7e 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,4 +1,8 @@
 version: '2'
+
+volumes:
+  graf-data:
+
 services:
   config-server:
     image: mszarlinski/spring-petclinic-config-server
@@ -91,3 +95,22 @@ services:
     entrypoint: ["./dockerize","-wait=tcp://discovery-server:8761","-timeout=60s","--","java", "-XX:+UnlockExperimentalVMOptions", "-XX:+UseCGroupMemoryLimitForHeap", "-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
     ports:
      - 7979:7979
+
+  ## Grafana / Prometheus
+
+  grafana-server:
+    image: grafana/grafana:5.2.4
+    container_name: grafana-server
+    mem_limit: 256M
+    ports:
+    - 3000:3000
+    volumes:
+    - graf-data:/var/lib/grafana
+
+  prometheus-server:
+    build: ./docker/prometheus
+    image: prometheus-local:v2.4.2
+    container_name: prometheus-server
+    mem_limit: 256M
+    ports:
+    - 9091:9090
diff --git a/docker/prometheus/Dockerfile b/docker/prometheus/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..58626f638cbe8799377e2389668077db2f35c4a4
--- /dev/null
+++ b/docker/prometheus/Dockerfile
@@ -0,0 +1,2 @@
+FROM prom/prometheus:v2.4.2
+ADD prometheus.yml /etc/prometheus/
diff --git a/docker/prometheus/prometheus.yml b/docker/prometheus/prometheus.yml
new file mode 100644
index 0000000000000000000000000000000000000000..30f089b72b1fea34e73f61bb4ae2418d05f679d7
--- /dev/null
+++ b/docker/prometheus/prometheus.yml
@@ -0,0 +1,32 @@
+# my global config
+global:
+  scrape_interval:     15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
+  evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
+  # scrape_timeout is set to the global default (10s).
+
+# A scrape configuration containing exactly one endpoint to scrape:
+# Here it's Prometheus itself.
+scrape_configs:
+- job_name: prometheus
+  static_configs:
+  - targets: ['localhost:9090']
+
+- job_name: api-gateway
+  metrics_path: /actuator/prometheus
+  static_configs:
+  - targets: ['api-gateway:8080']
+
+- job_name: customers-service
+  metrics_path: /actuator/prometheus
+  static_configs:
+  - targets: ['customers-service:8081']
+
+- job_name: visits-service
+  metrics_path: /actuator/prometheus
+  static_configs:
+  - targets: ['visits-service:8082']
+
+- job_name: vets-service
+  metrics_path: /actuator/prometheus
+  static_configs:
+  - targets: ['vets-service:8083']
diff --git a/pom.xml b/pom.xml
index 72c02e268390c8d1dea3fa8809a83a94a59ce441..1958e248768cf502a2b84bb34f7e1a554e1672f9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -33,6 +33,7 @@
         <spring-boot.version>2.0.4.RELEASE</spring-boot.version>
         <spring-cloud.version>Finchley.SR2</spring-cloud.version>
         <sleuth.version>2.0.0.RC2</sleuth.version>
+        <micrometer.version>1.0.5</micrometer.version>
 
         <maven-surefire-plugin.version>2.22.0</maven-surefire-plugin.version>
 
@@ -77,6 +78,19 @@
                 <version>${assertj.version}</version>
                 <scope>test</scope>
             </dependency>
+
+            <!-- Micrometer core dependency  -->
+            <dependency>
+                <groupId>io.micrometer</groupId>
+                <artifactId>micrometer-core</artifactId>
+                <version>${micrometer.version}</version>
+            </dependency>
+            <!-- Micrometer Prometheus registry  -->
+            <dependency>
+                <groupId>io.micrometer</groupId>
+                <artifactId>micrometer-registry-prometheus</artifactId>
+                <version>${micrometer.version}</version>
+            </dependency>
         </dependencies>
     </dependencyManagement>
 
diff --git a/spring-petclinic-api-gateway/pom.xml b/spring-petclinic-api-gateway/pom.xml
index 72370d2c3a6278fbf013fd2e97ab1134be47a43c..ae40e34eb04dc67f455d2d70230d02ab627cf1ea 100644
--- a/spring-petclinic-api-gateway/pom.xml
+++ b/spring-petclinic-api-gateway/pom.xml
@@ -87,6 +87,14 @@
             <groupId>org.projectlombok</groupId>
             <artifactId>lombok</artifactId>
         </dependency>
+        <dependency>
+            <groupId>io.micrometer</groupId>
+            <artifactId>micrometer-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.micrometer</groupId>
+            <artifactId>micrometer-registry-prometheus</artifactId>
+        </dependency>
 
         <!-- Webjars -->
         <dependency>
diff --git a/spring-petclinic-customers-service/pom.xml b/spring-petclinic-customers-service/pom.xml
index 6786f8346532e754c32c9fac3b21811f427c70ec..dc5928e477bcc4cda5d72006c66700d5d07c1ac7 100644
--- a/spring-petclinic-customers-service/pom.xml
+++ b/spring-petclinic-customers-service/pom.xml
@@ -77,6 +77,14 @@
 			<groupId>org.projectlombok</groupId>
 			<artifactId>lombok</artifactId>
 		</dependency>
+        <dependency>
+            <groupId>io.micrometer</groupId>
+            <artifactId>micrometer-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.micrometer</groupId>
+            <artifactId>micrometer-registry-prometheus</artifactId>
+        </dependency>
 
         <!-- Testing -->
         <dependency>
diff --git a/spring-petclinic-customers-service/src/main/java/org/springframework/samples/petclinic/customers/web/OwnerResource.java b/spring-petclinic-customers-service/src/main/java/org/springframework/samples/petclinic/customers/web/OwnerResource.java
index da748d0fa59a4cb75f74e7ddd8161ebec01100fc..80916f3efd0e60341bacff931fe56be06edfa759 100644
--- a/spring-petclinic-customers-service/src/main/java/org/springframework/samples/petclinic/customers/web/OwnerResource.java
+++ b/spring-petclinic-customers-service/src/main/java/org/springframework/samples/petclinic/customers/web/OwnerResource.java
@@ -15,6 +15,7 @@
  */
 package org.springframework.samples.petclinic.customers.web;
 
+import io.micrometer.core.instrument.MeterRegistry;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.http.HttpStatus;
@@ -40,6 +41,7 @@ import java.util.Optional;
 class OwnerResource {
 
     private final OwnerRepository ownerRepository;
+    private final MeterRegistry registry;
 
     /**
      * Create Owner
@@ -47,6 +49,7 @@ class OwnerResource {
     @PostMapping
     @ResponseStatus(HttpStatus.CREATED)
     public void createOwner(@Valid @RequestBody Owner owner) {
+        registry.counter("create.owner").increment();
         ownerRepository.save(owner);
     }
 
@@ -81,6 +84,7 @@ class OwnerResource {
         ownerModel.setAddress(ownerRequest.getAddress());
         ownerModel.setTelephone(ownerRequest.getTelephone());
         log.info("Saving owner {}", ownerModel);
+        registry.counter("update.owner").increment();
         return ownerRepository.save(ownerModel);
     }
 }
diff --git a/spring-petclinic-customers-service/src/main/java/org/springframework/samples/petclinic/customers/web/PetResource.java b/spring-petclinic-customers-service/src/main/java/org/springframework/samples/petclinic/customers/web/PetResource.java
index c657ca370fb09c8f65f6acb46690419b5fb21d73..34c8c70d6da7487791803f8fc8b6638ce6c3fdc7 100644
--- a/spring-petclinic-customers-service/src/main/java/org/springframework/samples/petclinic/customers/web/PetResource.java
+++ b/spring-petclinic-customers-service/src/main/java/org/springframework/samples/petclinic/customers/web/PetResource.java
@@ -15,6 +15,7 @@
  */
 package org.springframework.samples.petclinic.customers.web;
 
+import io.micrometer.core.instrument.MeterRegistry;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.http.HttpStatus;
@@ -36,8 +37,9 @@ import java.util.Optional;
 class PetResource {
 
     private final PetRepository petRepository;
-
     private final OwnerRepository ownerRepository;
+    private final MeterRegistry registry;
+
 
     @GetMapping("/petTypes")
     public List<PetType> getPetTypes() {
@@ -55,6 +57,7 @@ class PetResource {
         Owner owner = optionalOwner.orElseThrow(() -> new ResourceNotFoundException("Owner "+ownerId+" not found"));
         owner.addPet(pet);
 
+        registry.counter("create.pet").increment();
         save(pet, petRequest);
     }
 
@@ -63,6 +66,7 @@ class PetResource {
     public void processUpdateForm(@RequestBody PetRequest petRequest) {
         int petId = petRequest.getId();
         Pet pet = findPetById(petId);
+        registry.counter("update.pet").increment();
         save(pet, petRequest);
     }
 
diff --git a/spring-petclinic-customers-service/src/test/java/org/springframework/samples/petclinic/customers/web/PetResourceTest.java b/spring-petclinic-customers-service/src/test/java/org/springframework/samples/petclinic/customers/web/PetResourceTest.java
index 99313d23ebaf97a6c2ca2fc31ec9e035ff093dfb..5b2b3303c556b0efd3f1e1fd17a9d50a56cc3379 100644
--- a/spring-petclinic-customers-service/src/test/java/org/springframework/samples/petclinic/customers/web/PetResourceTest.java
+++ b/spring-petclinic-customers-service/src/test/java/org/springframework/samples/petclinic/customers/web/PetResourceTest.java
@@ -1,6 +1,8 @@
 package org.springframework.samples.petclinic.customers.web;
 
 import java.util.Optional;
+
+import io.micrometer.core.instrument.MeterRegistry;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -40,6 +42,9 @@ class PetResourceTest {
     @MockBean
     OwnerRepository ownerRepository;
 
+    @MockBean
+    MeterRegistry registry;
+
     @Test
     void shouldGetAPetInJSonFormat() throws Exception {
 
diff --git a/spring-petclinic-vets-service/pom.xml b/spring-petclinic-vets-service/pom.xml
index e7705a18d3f53a335acf20c4c93c879738b0498b..99b95770388e3001f753f5c1a1349d137fb523e7 100644
--- a/spring-petclinic-vets-service/pom.xml
+++ b/spring-petclinic-vets-service/pom.xml
@@ -93,6 +93,14 @@
 			<artifactId>mysql-connector-java</artifactId>
 			<scope>runtime</scope>
 		</dependency>
+        <dependency>
+            <groupId>io.micrometer</groupId>
+            <artifactId>micrometer-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.micrometer</groupId>
+            <artifactId>micrometer-registry-prometheus</artifactId>
+        </dependency>
 
         <!-- Testing -->
         <dependency>
diff --git a/spring-petclinic-visits-service/pom.xml b/spring-petclinic-visits-service/pom.xml
index ea9184d472b51f648aadb598c95732fe3c8e8f66..c60737406048892caf24887750a0a576bc6bbc50 100644
--- a/spring-petclinic-visits-service/pom.xml
+++ b/spring-petclinic-visits-service/pom.xml
@@ -76,6 +76,14 @@
 			<artifactId>mysql-connector-java</artifactId>
 			<scope>runtime</scope>
 		</dependency>
+        <dependency>
+            <groupId>io.micrometer</groupId>
+            <artifactId>micrometer-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.micrometer</groupId>
+            <artifactId>micrometer-registry-prometheus</artifactId>
+        </dependency>
 
         <!-- Testing -->
         <dependency>
diff --git a/spring-petclinic-visits-service/src/main/java/org/springframework/samples/petclinic/visits/web/VisitResource.java b/spring-petclinic-visits-service/src/main/java/org/springframework/samples/petclinic/visits/web/VisitResource.java
index 2ebab12e1b4fbc518d2d085e440d8c7161e4635f..5905f3715392fac0d3d7b59047ad84817caffd34 100644
--- a/spring-petclinic-visits-service/src/main/java/org/springframework/samples/petclinic/visits/web/VisitResource.java
+++ b/spring-petclinic-visits-service/src/main/java/org/springframework/samples/petclinic/visits/web/VisitResource.java
@@ -17,6 +17,8 @@ package org.springframework.samples.petclinic.visits.web;
 
 import java.util.List;
 import javax.validation.Valid;
+
+import io.micrometer.core.instrument.MeterRegistry;
 import lombok.RequiredArgsConstructor;
 import lombok.Value;
 import lombok.extern.slf4j.Slf4j;
@@ -44,6 +46,7 @@ import org.springframework.web.bind.annotation.RestController;
 class VisitResource {
 
     private final VisitRepository visitRepository;
+    private final MeterRegistry registry;
 
     @PostMapping("owners/*/pets/{petId}/visits")
     @ResponseStatus(HttpStatus.NO_CONTENT)
@@ -53,6 +56,7 @@ class VisitResource {
 
         visit.setPetId(petId);
         log.info("Saving visit {}", visit);
+        registry.counter("create.visit").increment();
         visitRepository.save(visit);
     }
 
diff --git a/spring-petclinic-visits-service/src/test/java/org/springframework/samples/petclinic/visits/web/VisitResourceTest.java b/spring-petclinic-visits-service/src/test/java/org/springframework/samples/petclinic/visits/web/VisitResourceTest.java
index 25d33f24ba7bba4bbd962752b6f05a98acd786d3..3409b30abd3b848b888586e422a7cb84bc294481 100644
--- a/spring-petclinic-visits-service/src/test/java/org/springframework/samples/petclinic/visits/web/VisitResourceTest.java
+++ b/spring-petclinic-visits-service/src/test/java/org/springframework/samples/petclinic/visits/web/VisitResourceTest.java
@@ -1,5 +1,6 @@
 package org.springframework.samples.petclinic.visits.web;
 
+import io.micrometer.core.instrument.MeterRegistry;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -29,6 +30,9 @@ class VisitResourceTest {
     @MockBean
     VisitRepository visitRepository;
 
+    @MockBean
+    MeterRegistry registry;
+
     @Test
     void shouldFetchVisits() throws Exception {
         given(visitRepository.findByPetIdIn(asList(111, 222)))