Litmus - Soaring Heights
Tags: litmuschaos, kubernetes, analytics, devops
Published: 2020-08-25 12:18:43

#**About LitmusChaos**
 <Enter>
![Alt text of image](https://raw.githubusercontent.com/litmuschaos/litmus/master/images/litmus-logo-white-bg-icon.png)
LitmusChaos provides a complete set of tools required by Kubernetes developers and SREs to carry out chaos tests easily and in Kubernetes-native way. LitmusChaos is a chaos engineering framework for Kubernetes.
The project has “Declarative Chaos” as the fundamental design goal and keeps the community at the center for growing the chaos experiments.
 <Enter>
###**Litmus broadly contains**
1.Chaos Operator
2.Chaos CRDs
3.Chaos experiments or the ChaosHub
4.Chaos Scheduler
5.Chaos metric exporter
6.Chaos events exporter
7.Portal
 <Enter>
###**In this blog, we’ll mainly talk about Litmus analytics.**
**Now, let's have a broad discussion about Analytics.**
 <Enter>
1.Analytics of Experiments and our Growth
2.Most popular places where Litmus users are located
3.Structure of maps and their dependencies
4.Loading Data and rending basic maps from libraries in React App
5.References and Links
 <Enter>
###**Analytics about users**
We are happy to share that our community has been reaching great heights these days, and we are happy to have achieved this milestone, and we are grateful to our users for supporting us always. Recently we have been getting a great response from the users and have a lot of active users. We are trying to expand our resources and our work worldwide.
 <Enter>

 ![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/fb2dlts4snywdczuhoe1.png)
Note: The above analytics data was noted on 25th Aug 2020.
 
In the current situation, we are experiencing Operator installed 14k+, Total Experiment Runs 108k+, Total Experiments 35 and Github star 1k+, and counting.
 <Enter>
####**Litmus Growth**
The below graph is showing the growth of our Litmus community based on Operator Experiment analytics.
 
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/899tpn2gqjw3yzt55fkx.png)
<Enter>
####**Experiments**
**Generic**: Pod Delete, Container Kill, Pod Network Latency, Pod Network Loss, Pod Network Corruption, Pod CPU Hog, Pod Memory Hog, Disk Fill, Disk Loss, Node CPU Hog, Node Memory Hog, Node Drain, Kubelet Service Kill, Pod Network Duplication, Node Taint, Docker Service Kill, Pod Autoscaler.
 
**Kubernetes**: Kubernetes Application Pod, Kubernetes Application Service, Kubernetes Cluster Level Pod - kiam, EC2 Terminate.
 
**OpenEBS**: Target Container Failure, Target Network Latency, Target Network Loss, Target Pod Failure, Pool Pod Failure, Pool Container Failure, Pool Network Latency, Pool Network Loss, Control Plane Chaos, cStor Pool Chaos, Pool Disk Loss, NFS Provisioner Kill.
 
**Kafka**: Broker Pod Failure, Broker Disk Failure, CoreDns CoreDNS Pod Delete, Cassandra Cassandra Pod Delete.
 <Enter>
###**Most popular places where Litmus users are located**

We have now crossed 170+ Cities and 35+ Countries worldwide where Litmus users are located. Currently, the top 10 countries are India, USA, China, Netherlands, France, Ukraine, Germany, Japan, Ireland, and Taiwan.
 <Enter>
####**City Wise Users**
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/qcgdzgvynaslofxb3xcc.png)
 <Enter>

Here the worldwide stats including the users from particular cities in the Map are shown.
 <Enter>
####**Country Wise Users**

 ![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/e7cr6j1t0cd27anpkvtb.png)
Here you can see our worldwide stats, including the users from particular countries in the Maps.
 <Enter>
###**Structure of maps and their dependencies**
 
To create a Geo map, one needs to have basic React knowledge. We have used React and TypeScript for development.
For the map, I used `react-simple-maps` for city-wise plotting and `react-google-charts` for country wise plotting.
 <Enter>
My approach was to plot data on Geo map using city wise, so it is good to show dots on the map to have proper visualization.
 <Enter>
Loading Data and rending basic maps from libraries in React App and Code

The code structure is :
```
┬ Litmus-Portal  
├─┬ backend
| └ frontend
|    ├─┬ src
|      └── components
|        ├─┬ GeoMap
│          ├── CityMap.tsx
|          ├── CountryMao.tsx
|          ├── index.ts 
│          └── geo.json
```
 <Enter>
####**CityMap**
The CityMap component will render a map based on the city-wise count of Chaos Experiments. Since I want to customize the projection for markers, so I take advantage of Marker property.
 <Enter>
Start by defining an interface for the name, and coordinates & data will be loaded asynchronously once the component mounts (useEffect()). Also, it will fetch geo.json to map the coordinates.
For the projection marker, I am keeping the same color for all with circle opacity.
 <Enter>
Required libraries are given below, and geoURL are coordinates of the World Map for mapping purposes.

 ```
import React, { useEffect, useState } from 'react';
import { useSelector } from 'react-redux';
import {
  ComposableMap,
  Geographies,
  Geography,
  Marker,
  ZoomableGroup,
} from 'react-simple-maps';
import { RootState } from '../../redux/reducers';
import datageo from './geo.json';
const geoUrl = datageo;
```

React components have a built-in state object, which stores the properties that belong to the Map component. When the state object changes, the component re-renders.

```
const [mapData, setMapData] = useState<CityData[]>([]);

  const geoCity = useSelector(
    (state: RootState) => state.communityData.google.geoCity
  );

  useEffect(() => {
    const cityData: CityData[] = [];
    geoCity.map((e) =>
      cityData.push({
        name: e.name,
        coordinates: [parseFloat(e.longitude), parseFloat(e.latitude)],
      })
    );
    setMapData(cityData);
```

**Adding a Map with marker**
To show data on each city map, I have added markers event listeners along with Composable Map and Zoomable Group.
 ```
     <ComposableMap style={{width: 640, height: 340,}}>
        <ZoomableGroup zoom={1.3}>
          <Geographies geography={geoUrl}>
            {({ geographies }) =>
              geographies.map((geo) => (
                <Geography
                  key={geo.rsmKey}
                  geography={geo}
                  fill="#CFCFCF"
                  stroke="#CFCFCF"
                />
              ))
            }
          </Geographies>
          {mapData &&
            mapData.map(({ name, coordinates }) => (
              <Marker key={`${name}_${coordinates}`} coordinates={coordinates}>
                <g
                  stroke="#858CDD"
                  strokeWidth="2"
                  strokeLinecap="round"
                  strokeLinejoin="round"
                  transform="translate(-12, -24)"
                >
                  <circle cx="12" cy="10" r="4" />
                </g>
              </Marker>
            ))}
        </ZoomableGroup>
      </ComposableMap>
```


####**CountryMap**
 
The CountryMap component will render a map based on the country-wise count of Experiments.
The approach is the same as CityMaps only difference is rendering a data country-wise and added hovering effects.
 <Enter>
Originally data is stored in states in 2D Array with Columns Country and Users so I have taken the CountryMap variable, which stores the properties that belong to the Map component. When the state object changes, the component re-renders.

```
const CountryMap = () => {
  const data: string[][] = useSelector(
    (state: RootState) => state.communityData.google.geoCountry
  );
  const parsedData = data.map((item) => [item[0], parseInt(item[1], 10)]);
  parsedData.unshift(['Country', 'Count'])
```
 
**Showing Gradient**
To give users an idea about the intensity of data, we can show a linear gradient with min = minimum of all values and max = maximum of all values.
 <Enter>
To show data on the hover of each country, we can add onMouseEnter and onMouseLeave event listeners, which shows the Country and Users from those countries.

``` 
   <Chart
        style={{ margin: 'auto' }}
        width="640px"
        height="340px"
        chartType="GeoChart"
        data={parsedData}
        options={{
          colorAxis: { colors: ['#2CCA8F', 'gray', '#5B44BA'] 
        },
          backgroundColor: '#ffffff',
          datalessRegionColor: '#CFCFCF',
          defaultColor: '#CFCFCF',
        }}
        rootProps={{ 'data-testid': '1' }}
      />
```

##**We are looking forward to the users contributing to our Litmus Community.**
<Enter>
###**References and Links**
[LitmusChaos](https://litmuschaos.io/)
[Litmus ChaosHub](https://hub.litmuschaos.io/)
[Github Repo Litmus](https://github.com/litmuschaos/litmus)
[Connect with us on Slack](https://kubernetes.slack.com/?redir=%2Farchives%2FCNXNB0ZTN)
[Litmus Chaos YouTube Channel](https://www.youtube.com/channel/UCa57PMqmz_j0wnteRa9nCaw)
 <Enter>
We are happy that we are contributing to the growth of our users and helping them rise and shine along with us.
<Enter>
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/t8n0251e5ipntdmcuulh.jpeg)