Merge pull request #27 from razorpay/PCORE-1896

PCORE-1896: Adding instrumentation in status page
pull/1097/head
Smit Patel 2022-06-10 17:12:42 +05:30 committed by GitHub
commit 609796d782
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 7701 additions and 5171 deletions

View File

@ -47,7 +47,9 @@ jobs:
tags: razorpay/statping:base_${{ github.sha }} tags: razorpay/statping:base_${{ github.sha }}
push: true push: true
file: ./Dockerfile.base file: ./Dockerfile.base
build-args: GIT_COMMIT_HASH=${{ github.sha }} build-args: |
GIT_COMMIT_HASH=${{ github.sha }}
GITHUB_ACCESS_TOKEN=${{ secrets.CI_BOT_TOKEN }}
cache-from: type=local,src=/tmp/.buildx-cache cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache cache-to: type=local,dest=/tmp/.buildx-cache
env: env:

View File

@ -1,6 +1,9 @@
FROM node:12.18.2-alpine AS frontend FROM node:16.13.0 AS frontend
LABEL maintainer="Hunter Long (https://github.com/hunterlong)" LABEL maintainer="Hunter Long (https://github.com/hunterlong)"
ARG BUILDPLATFORM ARG BUILDPLATFORM
ARG GITHUB_ACCESS_TOKEN
ENV GITHUB_ACCESS_TOKEN ${GITHUB_ACCESS_TOKEN}
# Build vue frontent # Build vue frontent
WORKDIR /statping WORKDIR /statping
@ -14,6 +17,7 @@ RUN yarn build && yarn cache clean
WORKDIR /statping-react WORKDIR /statping-react
COPY ./react-frontend/package.json . COPY ./react-frontend/package.json .
COPY ./react-frontend/yarn.lock . COPY ./react-frontend/yarn.lock .
COPY ./react-frontend/.npmrc .
RUN yarn install --pure-lockfile --network-timeout 1000000 RUN yarn install --pure-lockfile --network-timeout 1000000
COPY ./react-frontend/ . COPY ./react-frontend/ .
RUN yarn build && yarn cache clean RUN yarn build && yarn cache clean
@ -42,9 +46,9 @@ ENV GO111MODULE on
ENV CGO_ENABLED 1 ENV CGO_ENABLED 1
RUN go get github.com/stretchr/testify/assert && \ RUN go get github.com/stretchr/testify/assert && \
go get github.com/stretchr/testify/require && \ go get github.com/stretchr/testify/require && \
go get github.com/GeertJohan/go.rice/rice && \ go get github.com/GeertJohan/go.rice/rice && \
go get github.com/cortesi/modd/cmd/modd && \ go get github.com/cortesi/modd/cmd/modd && \
go get github.com/crazy-max/xgo go get github.com/crazy-max/xgo
COPY . . COPY . .
COPY --from=frontend /statping/dist/ ./source/dist/ COPY --from=frontend /statping/dist/ ./source/dist/
COPY --from=frontend /statping-react/build/ ./react/build/ COPY --from=frontend /statping-react/build/ ./react/build/

3
react-frontend/.npmrc Normal file
View File

@ -0,0 +1,3 @@
@razorpay:registry=https://npm.pkg.github.com/
//npm.pkg.github.com/:always-auth=true
//npm.pkg.github.com/:_authToken=${GITHUB_ACCESS_TOKEN}

View File

@ -0,0 +1,2 @@
REACT_APP_LUMBERJACK_API_URL="https://lumberjack.stage.razorpay.in/v1/track"
REACT_APP_LUMBERJACK_API_KEY='UHjKbQGfxNrh9p2Die2vcu06alGtijkj'

View File

@ -0,0 +1,2 @@
REACT_APP_LUMBERJACK_API_URL="https://lumberjack.razorpay.com/v1/track"
REACT_APP_LUMBERJACK_API_KEY='FsXeGGD0S8uVBnfqlgkBXE4Ht2ZH9Y9c'

View File

@ -3,8 +3,8 @@
"version": "0.1.0", "version": "0.1.0",
"private": true, "private": true,
"scripts": { "scripts": {
"start": "react-scripts start", "start": "env-cmd -f ./configs/dev.env react-scripts start",
"build": "rm -rf build && GENERATE_SOURCEMAP=false react-scripts build", "build": "rm -rf build && GENERATE_SOURCEMAP=false env-cmd -f ./configs/prod.env react-scripts build",
"test": "react-scripts test", "test": "react-scripts test",
"eject": "react-scripts eject" "eject": "react-scripts eject"
}, },
@ -17,16 +17,18 @@
"@fortawesome/fontawesome-svg-core": "^1.2.36", "@fortawesome/fontawesome-svg-core": "^1.2.36",
"@fortawesome/free-solid-svg-icons": "^5.15.4", "@fortawesome/free-solid-svg-icons": "^5.15.4",
"@fortawesome/react-fontawesome": "^0.1.15", "@fortawesome/react-fontawesome": "^0.1.15",
"@razorpay/universe-utils": "^5.1.2",
"apexcharts": "^3.28.1", "apexcharts": "^3.28.1",
"axios": "^0.21.1", "axios": "^0.21.1",
"date-fns": "^2.23.0", "date-fns": "^2.23.0",
"env-cmd": "^10.1.0",
"framer-motion": "^4", "framer-motion": "^4",
"node-sass": "^6.0.1", "node-sass": "^6.0.1",
"react": "^17.0.2", "react": "^17.0.2",
"react-apexcharts": "^1.3.9", "react-apexcharts": "^1.3.9",
"react-dom": "^17.0.2", "react-dom": "^17.0.2",
"react-router-dom": "^5.2.0", "react-router-dom": "^5.2.0",
"react-scripts": "4.0.3", "react-scripts": "^5.0.1",
"react-tooltip": "^4.2.21" "react-tooltip": "^4.2.21"
}, },
"eslintConfig": { "eslintConfig": {

View File

@ -36,4 +36,8 @@
To create a production bundle, use `npm run build` or `yarn build`. To create a production bundle, use `npm run build` or `yarn build`.
--> -->
</body> </body>
<script type="text/javaScript">
window.LUMBERJACK_API_URL = "%REACT_APP_LUMBERJACK_API_URL%";
window.LUMBERJACK_API_KEY = "%REACT_APP_LUMBERJACK_API_KEY%";
</script>
</html> </html>

View File

@ -1,12 +1,20 @@
import React from "react"; import React, { useEffect } from "react";
import { BrowserRouter, Switch, Route, Redirect } from "react-router-dom"; import { BrowserRouter, Switch, Route, Redirect } from "react-router-dom";
import { ChakraProvider } from "@chakra-ui/react"; import { ChakraProvider } from "@chakra-ui/react";
import theme from "../theme"; import theme from "../theme";
import ServicesPage from "./ServicesPage"; import ServicesPage from "./ServicesPage";
import Navigation from "./Navbar"; import Navigation from "./Navbar";
import { initLumberjack } from "../utils/trackers";
import { generateUUID, getUserId, setUerId } from "../utils/helper";
const App = () => { const App = () => {
console.log(`Application running on ${process.env.NODE_ENV} mode.`); useEffect(() => {
if(!getUserId()) {
setUerId(generateUUID(14));
}
initLumberjack();
}, [])
return ( return (
<ChakraProvider theme={theme}> <ChakraProvider theme={theme}>

View File

@ -1,6 +1,15 @@
import React from "react"; import React from "react";
import { analyticsTrack } from "../utils/trackers";
const ContentHeader = () => { const ContentHeader = () => {
const sendAnalytics = () => {
analyticsTrack({
objectName: 'Support Page',
actionName: 'clicked',
screen: 'Home page'
})
}
return ( return (
<div className="header"> <div className="header">
<h1 className="header-title mt-4 mb-3 font-24 fw-700"> <h1 className="header-title mt-4 mb-3 font-24 fw-700">
@ -13,6 +22,7 @@ const ContentHeader = () => {
real-time, operational issue with one of our products that is not real-time, operational issue with one of our products that is not
described below, please reach out to{" "} described below, please reach out to{" "}
<a <a
onClick={sendAnalytics}
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
href="https://razorpay.com/support/" href="https://razorpay.com/support/"

View File

@ -6,10 +6,8 @@ import API from "../config/API";
import langs from "../config/langs"; import langs from "../config/langs";
import GroupServiceFailures from "./GroupServiceFailures"; import GroupServiceFailures from "./GroupServiceFailures";
import SubServiceCard from "./SubServiceCard"; import SubServiceCard from "./SubServiceCard";
// import IncidentsBlock from "./IncidentsBlock";
// import ServiceLoader from "./ServiceLoader";
// import DateUtils from "../utils/DateUtils";
import infoIcon from "../static/info.svg"; import infoIcon from "../static/info.svg";
import { analyticsTrack } from "../utils/trackers";
const GroupItem = ({ service, showPlusButton }) => { const GroupItem = ({ service, showPlusButton }) => {
const [collapse, setCollapse] = useState(false); const [collapse, setCollapse] = useState(false);
@ -17,10 +15,6 @@ const GroupItem = ({ service, showPlusButton }) => {
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [hoverText, setHoverText] = useState(""); const [hoverText, setHoverText] = useState("");
// const groupServices = services
// .filter((s) => s.group_id === service.id)
// .sort((a, b) => a.order_id - b.order_id);
const fetchSubServices = async () => { const fetchSubServices = async () => {
const data = await API.fetchSubServices(service.id); const data = await API.fetchSubServices(service.id);
if (Array.isArray(data)) { if (Array.isArray(data)) {
@ -30,7 +24,7 @@ const GroupItem = ({ service, showPlusButton }) => {
setCollapse(true); setCollapse(true);
}; };
const openCollapse = () => { const openCollapse = (event) => {
if (subServices.length === 0) { if (subServices.length === 0) {
setLoading(true); setLoading(true);
try { try {
@ -43,10 +37,28 @@ const GroupItem = ({ service, showPlusButton }) => {
} else { } else {
setCollapse(true); setCollapse(true);
} }
analyticsTrack({
objectName: 'Service Expand',
actionName: 'clicked',
screen: 'Home page',
properties:{
serviceName: event.target.name,
}
})
}; };
const closeCollapse = () => { const closeCollapse = (event) => {
setCollapse(false); setCollapse(false);
analyticsTrack({
objectName: 'Service Collapse',
actionName: 'clicked',
screen: 'Home page',
properties:{
serviceName: event.target.name,
}
})
}; };
const handleMouseOver = (service) => { const handleMouseOver = (service) => {
@ -63,9 +75,9 @@ const GroupItem = ({ service, showPlusButton }) => {
{!loading && showPlusButton && ( {!loading && showPlusButton && (
<> <>
{collapse ? ( {collapse ? (
<button className="square-minus" onClick={closeCollapse} /> <button className="square-minus" name={service.name} onClick={closeCollapse} />
) : ( ) : (
<button className="square-plus" onClick={openCollapse} /> <button className="square-plus" name={service.name} onClick={openCollapse} />
)} )}
</> </>
)} )}

View File

@ -3,13 +3,24 @@ import { Box, Tooltip } from "@chakra-ui/react";
import Link from "../Link"; import Link from "../Link";
import Image from "../Image"; import Image from "../Image";
import Button from "../Button"; import Button from "../Button";
import analyticsService from '@razorpay/universe-utils/analytics';
import RzpLogo from "../../static/razorpay-logo-white.svg"; import RzpLogo from "../../static/razorpay-logo-white.svg";
import indiaFlagSvg from "./images/india-flag.svg"; import indiaFlagSvg from "./images/india-flag.svg";
import { analyticsTrack } from "../../utils/trackers";
const RazorpayLogoLink = () => ( const sendAnalytics = (event) => {
<Link analyticsTrack({
objectName: event.target.name || 'home page',
actionName: 'clicked',
screen: 'Home page'
})
}
const RazorpayLogoLink = () => {
return <Link
to="https://razorpay.com/" to="https://razorpay.com/"
onClick={sendAnalytics}
isExternal isExternal
py={{ xxs: "6", lg: "7" }} py={{ xxs: "6", lg: "7" }}
paddingRight={{ xxs: "0", lg: "22" }} paddingRight={{ xxs: "0", lg: "22" }}
@ -24,7 +35,7 @@ const RazorpayLogoLink = () => (
alt="Razorpay Logo" alt="Razorpay Logo"
/> />
</Link> </Link>
); };
const Navigation = () => { const Navigation = () => {
return ( return (
@ -67,7 +78,10 @@ const Navigation = () => {
</Tooltip> </Tooltip>
<Button <Button
as={Link} as={Link}
onClick={sendAnalytics}
type="button"
size="sm" size="sm"
name="login"
colorScheme="link" colorScheme="link"
to="https://dashboard.razorpay.com/#/access/signin" to="https://dashboard.razorpay.com/#/access/signin"
> >
@ -75,9 +89,12 @@ const Navigation = () => {
</Button> </Button>
<Button <Button
as={Link} as={Link}
onClick={sendAnalytics}
type="button"
to="https://dashboard.razorpay.com/signup" to="https://dashboard.razorpay.com/signup"
marginLeft={{ base: "1", xs: "4" }} marginLeft={{ base: "1", xs: "4" }}
size="sm" size="sm"
name="signup"
colorScheme="white" colorScheme="white"
display={{ base: "none", xxs: "none", lg: "inline-block" }} display={{ base: "none", xxs: "none", lg: "inline-block" }}
> >

View File

@ -12,6 +12,7 @@ import ServiceLoader from "./ServiceLoader";
import API from "../config/API"; import API from "../config/API";
import { STATUS_COLOR, STATUS_ICON, STATUS_TEXT } from "../utils/constants"; import { STATUS_COLOR, STATUS_ICON, STATUS_TEXT } from "../utils/constants";
import { findStatus } from "../utils/helper"; import { findStatus } from "../utils/helper";
import { analyticsTrack } from "../utils/trackers";
const ServicesPage = () => { const ServicesPage = () => {
// const data = messages.filter((m) => inRange(m) && m.service === 0); // const data = messages.filter((m) => inRange(m) && m.service === 0);
@ -21,6 +22,16 @@ const ServicesPage = () => {
const [poll, setPolling] = useState(1); const [poll, setPolling] = useState(1);
const today = DateUtils.format(new Date(), "d MMMM yyyy, hh:mm aaa"); const today = DateUtils.format(new Date(), "d MMMM yyyy, hh:mm aaa");
useEffect(() => {
if(!loading) {
analyticsTrack({
objectName: 'Status Page',
actionName: 'displayed',
screen: 'Home page'
})
}
}, [loading])
useEffect(() => { useEffect(() => {
const timer = setInterval(() => { const timer = setInterval(() => {
setPolling((prev) => (prev += 1)); setPolling((prev) => (prev += 1));

View File

@ -57,3 +57,15 @@ export const calcPer = (uptime, downtime) => {
// }); // });
// return arrayStr.join("<br/>"); // return arrayStr.join("<br/>");
// } // }
export const setUerId = (id) => {
localStorage.setItem('stat_user_id',id);
}
export const getUserId = () => {
return localStorage.getItem('stat_user_id');
}
export const generateUUID = (length) => {
return Array.from(Array(length), () => Math.floor(Math.random() * 36).toString(36)).join('')
}

20
react-frontend/src/utils/trackers.js vendored Normal file
View File

@ -0,0 +1,20 @@
import analyticsService from '@razorpay/universe-utils/analytics';
import { getUserId } from './helper';
export const initLumberjack = () => {
analyticsService.init({
lumberjackAppName: 'external_status_page',
lumberjackApiKey: window.LUMBERJACK_API_KEY,
lumberjackApiUrl: window.LUMBERJACK_API_URL,
});
};
export const analyticsTrack = (trackObj) => {
analyticsService.track({
...trackObj,
properties: {
...trackObj.properties,
userId: getUserId(),
},
});
};

File diff suppressed because it is too large Load Diff