CINXE.COM

GrafLI - An out-of-the-box Azure monitoring and visualization platform

<!DOCTYPE html> <html lang="en"> <head> <meta name="pageKey" content="d_lithograph_content"> <!----><!----> <meta name="locale" content="en_US"> <meta id="config" data-app-id="lithograph" data-app-version="0.0.1084" data-call-tree-id="AAYnj7ClcaRATYiUgFnMWA==" data-multiproduct-name="lithograph-publish-frontend" data-service-name="lithograph-publish-frontend" data-browser-id="0a1c7582-53d3-4db2-8669-6059003642cd" data-page-instance="urn:li:page:d_lithograph_content;CNJzlvWYRhmgaBk5qAVD7Q==" data-disable-jsbeacon-pagekey-suffix="false"> <link rel="canonical" href="https://www.linkedin.com/blog/engineering/analytics/grafli-an-out-of-the-box-azure-monitoring-visualization-platform"> <!----><!----> <!----> <!----> <!----> <link rel="manifest" href="/homepage-guest/manifest.json" crossorigin="use-credentials"> <link rel="icon" href="https://static.licdn.com/aero-v1/sc/h/al2o9zrvru7aqj8e1x2rzsrca"> <script> function getDfd() {let yFn,nFn;const p=new Promise(function(y, n){yFn=y;nFn=n;});p.resolve=yFn;p.reject=nFn;return p;} window.lazyloader = getDfd(); window.tracking = getDfd(); window.impressionTracking = getDfd(); window.ingraphTracking = getDfd(); window.appDetection = getDfd(); window.pemTracking = getDfd(); </script> <!----> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>GrafLI - An out-of-the-box Azure monitoring and visualization platform</title> <!----> <meta property="og:type" content="website"> <meta property="og:title" content="GrafLI - An out-of-the-box Azure monitoring and visualization platform"> <!----> <meta property="og:url" content="https://www.linkedin.com/blog/engineering/analytics/grafli-an-out-of-the-box-azure-monitoring-visualization-platform"> <meta property="og:image" content="https://media.licdn.com/dms/image/v2/D4D08AQHrOl9S1GeiaA/croft-frontend-shrinkToFit1024/croft-frontend-shrinkToFit1024/0/1711562654168?e=2147483647&amp;v=beta&amp;t=nS0v3ji5HCi2TR5PjYNWXfvtgkqlzeW-_ncb66oyjew"> <meta name="twitter:title" content="GrafLI - An out-of-the-box Azure monitoring and visualization platform"> <meta name="twitter:site" content="@linkedin"> <!----> <!----> <meta name="robots" content="noarchive"> <meta name="linkedin:pageTag" content="/blog/engineering/analytics/grafli-an-out-of-the-box-azure-monitoring-visualization-platform"> <meta name="litmsProfileName" content="lithograph"> <!----> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="asset-url" id="artdeco/static/images/icons.svg" content="https://static.licdn.com/aero-v1/sc/h/6sz1e821vgereyxaakx87tt4z "> <link rel="stylesheet" href="https://static.licdn.com/aero-v1/sc/h/crjcj3vgj0tgpae2eu4u9y7eb"> <!----> <!----> </head> <body dir="ltr"> <!----> <a href="#lithograph-app" class="skip-link btn-md btn-primary absolute z-11 -top-[100vh] focus:top-0"> Skip to main content </a> <!----> <div class="page-header__wrapper page-header__wrapper--margin" data-custom-nav-wrapper="true"> <div class="page-header__container"> <header id="page-header" class="page-header page-header--hide-dropshadow"> <div class="page-header__content-container"> <div class="header__logo"> <a href="https://www.linkedin.com/blog/engineering" class="custom-nav__logo-link"> <img class="header__linkedin-logo header__full-logo" src="https://static.licdn.com/aero-v1/sc/h/6zm111mce7vohqze950ilreo4" alt="LinkedIn Logo"> <img class="header__linkedin-logo header__in-bug" src="https://static.licdn.com/aero-v1/sc/h/5g0hjlcng3j5pgn50n2et1ca2" alt="LinkedIn Logo"> <span class="t-17 t-black t-bold default-header-title"> Engineering Blog </span> </a> </div> <!----> <!----> <button class="stripped header__expand-nav-button" data-mobile-header-navigation-button data-header-expand-navigation-button aria-expanded="false"> <li-icon class="header__expand-nav-icon" a11y-text="Open navigation" type="hamburger-icon"></li-icon> </button> <button class="stripped header__expand-nav-button hidden" data-mobile-header-navigation-button data-header-collapse-navigation-button aria-expanded="false"> <li-icon class="header__expand-nav-icon" a11y-text="Close navigation" type="cancel-icon"></li-icon> </button> </div> </header> </div> <nav class="header-nav fixed" aria-label="main" data-header-navigation> <ul class="header-nav__list"> <li> <div class="artdeco-dropdown"> <div class="artdeco-dropdown__trigger"> <a href="https://www.linkedin.com/blog/engineering/data" class="t-sans t-black--light t-semibold header-nav__toplink" target="_self"> Data </a> <button class="header-navigation__button" aria-label="Expand to show more links for Data" aria-expanded="false" data-trigger-dropdown-menu type="button"> <li-icon size="small" type="caret-filled-down-icon"></li-icon> </button> <div class="artdeco-dropdown__content header-nav__dropdown-offset"> <ul> <li> <div class="artdeco-dropdown__item"> <a href="https://www.linkedin.com/blog/engineering/graph-systems" class="t-14 t-sans t-black t-bold header-nav__link" target="_self">Graph System</a> </div> </li> <li> <div class="artdeco-dropdown__item"> <a href="https://www.linkedin.com/blog/engineering/economic-graph" class="t-14 t-sans t-black t-bold header-nav__link" target="_self">Economic Graph</a> </div> </li> <li> <div class="artdeco-dropdown__item"> <a href="https://www.linkedin.com/blog/engineering/skills-graph" class="t-14 t-sans t-black t-bold header-nav__link" target="_self">Skills Graph</a> </div> </li> <li> <div class="artdeco-dropdown__item"> <a href="https://www.linkedin.com/blog/engineering/knowledge" class="t-14 t-sans t-black t-bold header-nav__link" target="_self">Knowledge Graph</a> </div> </li> <li> <div class="artdeco-dropdown__item"> <a href="https://www.linkedin.com/blog/engineering/data-management" class="t-14 t-sans t-black t-bold header-nav__link" target="_self">Data Management</a> </div> </li> <li> <div class="artdeco-dropdown__item"> <a href="https://www.linkedin.com/blog/engineering/data-streaming-processing" class="t-14 t-sans t-black t-bold header-nav__link" target="_self">Data Streams/Processing</a> </div> </li> <li> <div class="artdeco-dropdown__item"> <a href="https://www.linkedin.com/blog/engineering/data-science" class="t-14 t-sans t-black t-bold header-nav__link" target="_self">Data Science</a> </div> </li> <li> <div class="artdeco-dropdown__item"> <a href="https://www.linkedin.com/blog/engineering/research" class="t-14 t-sans t-black t-bold header-nav__link" target="_self">Research</a> </div> </li> <li> <div class="artdeco-dropdown__item"> <a href="https://www.linkedin.com/blog/engineering/ab-testing-experimentation" class="t-14 t-sans t-black t-bold header-nav__link" target="_self">A/B Testing/Experimentation</a> </div> </li> </ul> </div> </div> </div> </li> <li> <div class="artdeco-dropdown"> <div class="artdeco-dropdown__trigger"> <a href="https://www.linkedin.com/blog/engineering/artificial-intelligence" class="t-sans t-black--light t-semibold header-nav__toplink" target="_self"> AI </a> <button class="header-navigation__button" aria-label="Expand to show more links for AI" aria-expanded="false" data-trigger-dropdown-menu type="button"> <li-icon size="small" type="caret-filled-down-icon"></li-icon> </button> <div class="artdeco-dropdown__content header-nav__dropdown-offset"> <ul> <li> <div class="artdeco-dropdown__item"> <a href="https://www.linkedin.com/blog/engineering/machine-learning" class="t-14 t-sans t-black t-bold header-nav__link" target="_self">Machine Learning</a> </div> </li> <li> <div class="artdeco-dropdown__item"> <a href="https://www.linkedin.com/blog/engineering/natural-language-processing" class="t-14 t-sans t-black t-bold header-nav__link" target="_self">Natural Language Processing</a> </div> </li> <li> <div class="artdeco-dropdown__item"> <a href="https://www.linkedin.com/blog/engineering/generative-ai" class="t-14 t-sans t-black t-bold header-nav__link" target="_self">Generative AI</a> </div> </li> <li> <div class="artdeco-dropdown__item"> <a href="https://www.linkedin.com/blog/engineering/data-modeling" class="t-14 t-sans t-black t-bold header-nav__link" target="_self">Data Modeling</a> </div> </li> <li> <div class="artdeco-dropdown__item"> <a href="https://www.linkedin.com/blog/engineering/responsible-ai" class="t-14 t-sans t-black t-bold header-nav__link" target="_self">Responsible AI</a> </div> </li> </ul> </div> </div> </div> </li> <li> <div class="artdeco-dropdown"> <div class="artdeco-dropdown__trigger"> <a href="https://www.linkedin.com/blog/engineering/trust-and-safety" class="t-sans t-black--light t-semibold header-nav__toplink" target="_self"> Trust &amp; Safety </a> <button class="header-navigation__button" aria-label="Expand to show more links for Trust &amp;amp; Safety" aria-expanded="false" data-trigger-dropdown-menu type="button"> <li-icon size="small" type="caret-filled-down-icon"></li-icon> </button> <div class="artdeco-dropdown__content header-nav__dropdown-offset"> <ul> <li> <div class="artdeco-dropdown__item"> <a href="https://www.linkedin.com/blog/engineering/fairness" class="t-14 t-sans t-black t-bold header-nav__link" target="_self">Fairness</a> </div> </li> <li> <div class="artdeco-dropdown__item"> <a href="https://www.linkedin.com/blog/engineering/verification" class="t-14 t-sans t-black t-bold header-nav__link" target="_self">Verification </a> </div> </li> <li> <div class="artdeco-dropdown__item"> <a href="https://www.linkedin.com/blog/engineering/security" class="t-14 t-sans t-black t-bold header-nav__link" target="_self">Security</a> </div> </li> </ul> </div> </div> </div> </li> <li> <div class="artdeco-dropdown"> <div class="artdeco-dropdown__trigger"> <a href="https://www.linkedin.com/blog/engineering/product-design" class="t-sans t-black--light t-semibold header-nav__toplink" target="_self"> Product Design </a> <button class="header-navigation__button" aria-label="Expand to show more links for Product Design" aria-expanded="false" data-trigger-dropdown-menu type="button"> <li-icon size="small" type="caret-filled-down-icon"></li-icon> </button> <div class="artdeco-dropdown__content header-nav__dropdown-offset"> <ul> <li> <div class="artdeco-dropdown__item"> <a href="https://www.linkedin.com/blog/engineering/marketing" class="t-14 t-sans t-black t-bold header-nav__link" target="_self">Marketing </a> </div> </li> <li> <div class="artdeco-dropdown__item"> <a href="https://www.linkedin.com/blog/engineering/sales" class="t-14 t-sans t-black t-bold header-nav__link" target="_self">Sales</a> </div> </li> <li> <div class="artdeco-dropdown__item"> <a href="https://www.linkedin.com/blog/engineering/learning" class="t-14 t-sans t-black t-bold header-nav__link" target="_self">Learning</a> </div> </li> <li> <div class="artdeco-dropdown__item"> <a href="https://www.linkedin.com/blog/engineering/hiring" class="t-14 t-sans t-black t-bold header-nav__link" target="_self">Hiring</a> </div> </li> <li> <div class="artdeco-dropdown__item"> <a href="https://www.linkedin.com/blog/engineering/profile" class="t-14 t-sans t-black t-bold header-nav__link" target="_self">Profile</a> </div> </li> <li> <div class="artdeco-dropdown__item"> <a href="https://www.linkedin.com/blog/engineering/messaging-notifications" class="t-14 t-sans t-black t-bold header-nav__link" target="_self">Messaging/Notifications</a> </div> </li> <li> <div class="artdeco-dropdown__item"> <a href="https://www.linkedin.com/blog/engineering/feed" class="t-14 t-sans t-black t-bold header-nav__link" target="_self">Feed</a> </div> </li> <li> <div class="artdeco-dropdown__item"> <a href="https://www.linkedin.com/blog/engineering/profile" class="t-14 t-sans t-black t-bold header-nav__link" target="_self">Profile</a> </div> </li> <li> <div class="artdeco-dropdown__item"> <a href="https://www.linkedin.com/blog/engineering/groups" class="t-14 t-sans t-black t-bold header-nav__link" target="_self">Groups</a> </div> </li> <li> <div class="artdeco-dropdown__item"> <a href="https://www.linkedin.com/blog/engineering/accessibility" class="t-14 t-sans t-black t-bold header-nav__link" target="_self">Accessibility</a> </div> </li> <li> <div class="artdeco-dropdown__item"> <a href="https://www.linkedin.com/blog/engineering/member-customer-experience" class="t-14 t-sans t-black t-bold header-nav__link" target="_self">Member/Customer Experience</a> </div> </li> <li> <div class="artdeco-dropdown__item"> <a href="https://www.linkedin.com/blog/engineering/search" class="t-14 t-sans t-black t-bold header-nav__link" target="_self">Search</a> </div> </li> <li> <div class="artdeco-dropdown__item"> <a href="https://www.linkedin.com/blog/engineering/recommendations" class="t-14 t-sans t-black t-bold header-nav__link" target="_self">Recommendations</a> </div> </li> <li> <div class="artdeco-dropdown__item"> <a href="https://www.linkedin.com/blog/engineering/skills" class="t-14 t-sans t-black t-bold header-nav__link" target="_self">Skills</a> </div> </li> </ul> </div> </div> </div> </li> <li> <div class="artdeco-dropdown"> <div class="artdeco-dropdown__trigger"> <a href="https://www.linkedin.com/blog/engineering/infrastructure" class="t-sans t-black--light t-semibold header-nav__toplink" target="_self"> Infrastructure </a> <button class="header-navigation__button" aria-label="Expand to show more links for Infrastructure" aria-expanded="false" data-trigger-dropdown-menu type="button"> <li-icon size="small" type="caret-filled-down-icon"></li-icon> </button> <div class="artdeco-dropdown__content header-nav__dropdown-offset"> <ul> <li> <div class="artdeco-dropdown__item"> <a href="https://www.linkedin.com/blog/engineering/code" class="t-14 t-sans t-black t-bold header-nav__link" target="_self">Code</a> </div> </li> <li> <div class="artdeco-dropdown__item"> <a href="https://www.linkedin.com/blog/engineering/scalability" class="t-14 t-sans t-black t-bold header-nav__link" target="_self">Scalability</a> </div> </li> <li> <div class="artdeco-dropdown__item"> <a href="https://www.linkedin.com/blog/engineering/distributed-systems" class="t-14 t-sans t-black t-bold header-nav__link" target="_self">Distributed Systems</a> </div> </li> <li> <div class="artdeco-dropdown__item"> <a href="https://www.linkedin.com/blog/engineering/graph-systems" class="t-14 t-sans t-black t-bold header-nav__link" target="_self">Graph Systems</a> </div> </li> <li> <div class="artdeco-dropdown__item"> <a href="https://www.linkedin.com/blog/engineering/architecture" class="t-14 t-sans t-black t-bold header-nav__link" target="_self">Architecture</a> </div> </li> <li> <div class="artdeco-dropdown__item"> <a href="https://www.linkedin.com/blog/engineering/analytics" class="t-14 t-sans t-black t-bold header-nav__link" target="_self">Analytics</a> </div> </li> <li> <div class="artdeco-dropdown__item"> <a href="https://www.linkedin.com/blog/engineering/automation" class="t-14 t-sans t-black t-bold header-nav__link" target="_self">Automation</a> </div> </li> <li> <div class="artdeco-dropdown__item"> <a href="https://www.linkedin.com/blog/engineering/platform-platformization" class="t-14 t-sans t-black t-bold header-nav__link" target="_self">Platforms/Platformization</a> </div> </li> <li> <div class="artdeco-dropdown__item"> <a href="https://www.linkedin.com/blog/engineering/cloud-computing" class="t-14 t-sans t-black t-bold header-nav__link" target="_self">Cloud Computing</a> </div> </li> <li> <div class="artdeco-dropdown__item"> <a href="https://www.linkedin.com/blog/engineering/open-source" class="t-14 t-sans t-black t-bold header-nav__link" target="_self">Open Source</a> </div> </li> <li> <div class="artdeco-dropdown__item"> <a href="https://www.linkedin.com/blog/engineering/additional-innovations" class="t-14 t-sans t-black t-bold header-nav__link" target="_self">Additional Innovations</a> </div> </li> </ul> </div> </div> </div> </li> <li> <div class="artdeco-dropdown"> <div class="artdeco-dropdown__trigger"> <a href="https://www.linkedin.com/blog/engineering/talent" class="t-sans t-black--light t-semibold header-nav__toplink" target="_self"> Talent </a> <button class="header-navigation__button" aria-label="Expand to show more links for Talent" aria-expanded="false" data-trigger-dropdown-menu type="button"> <li-icon size="small" type="caret-filled-down-icon"></li-icon> </button> <div class="artdeco-dropdown__content header-nav__dropdown-offset"> <ul> <li> <div class="artdeco-dropdown__item"> <a href="https://www.linkedin.com/blog/engineering/culture" class="t-14 t-sans t-black t-bold header-nav__link" target="_self">Culture</a> </div> </li> <li> <div class="artdeco-dropdown__item"> <a href="https://www.linkedin.com/blog/engineering/developer-experience-productivity" class="t-14 t-sans t-black t-bold header-nav__link" target="_self">Developer Experience/Productivity</a> </div> </li> <li> <div class="artdeco-dropdown__item"> <a href="https://www.linkedin.com/blog/engineering/leadership" class="t-14 t-sans t-black t-bold header-nav__link" target="_self">Leadership</a> </div> </li> </ul> </div> </div> </div> </li> </ul> </nav> <nav class="custom-header__nav--mobile invisible" data-mobile-navigation="true" aria-label="main"> <ul class="custom-header__list--mobile"> <li class="custom-header__list-item--mobile" data-mobile-navigation-list-item="true"> <a href="https://www.linkedin.com/blog/engineering/data" class="t-16 t-sans t-black t-semibold header-nav__toplink" target="_self"> Data </a> <button class="header-navigation__button" aria-label="Expand to show more links for Data" aria-expanded="false" data-mobile-dropdown-trigger type="button"> <li-icon size="small" type="chevron-down-icon"></li-icon> </button> <ul class="custom-header__dropdownlink-list--mobile hidden" data-dropdownlinks-list="true"> <li> <a href="https://www.linkedin.com/blog/engineering/graph-systems" class="t-sans t-black t-normal header-nav__link" target="_self">Graph System</a> </li> <li> <a href="https://www.linkedin.com/blog/engineering/economic-graph" class="t-sans t-black t-normal header-nav__link" target="_self">Economic Graph</a> </li> <li> <a href="https://www.linkedin.com/blog/engineering/skills-graph" class="t-sans t-black t-normal header-nav__link" target="_self">Skills Graph</a> </li> <li> <a href="https://www.linkedin.com/blog/engineering/knowledge" class="t-sans t-black t-normal header-nav__link" target="_self">Knowledge Graph</a> </li> <li> <a href="https://www.linkedin.com/blog/engineering/data-management" class="t-sans t-black t-normal header-nav__link" target="_self">Data Management</a> </li> <li> <a href="https://www.linkedin.com/blog/engineering/data-streaming-processing" class="t-sans t-black t-normal header-nav__link" target="_self">Data Streams/Processing</a> </li> <li> <a href="https://www.linkedin.com/blog/engineering/data-science" class="t-sans t-black t-normal header-nav__link" target="_self">Data Science</a> </li> <li> <a href="https://www.linkedin.com/blog/engineering/research" class="t-sans t-black t-normal header-nav__link" target="_self">Research</a> </li> <li> <a href="https://www.linkedin.com/blog/engineering/ab-testing-experimentation" class="t-sans t-black t-normal header-nav__link" target="_self">A/B Testing/Experimentation</a> </li> </ul> </li> <li class="custom-header__list-item--mobile" data-mobile-navigation-list-item="true"> <a href="https://www.linkedin.com/blog/engineering/artificial-intelligence" class="t-16 t-sans t-black t-semibold header-nav__toplink" target="_self"> AI </a> <button class="header-navigation__button" aria-label="Expand to show more links for AI" aria-expanded="false" data-mobile-dropdown-trigger type="button"> <li-icon size="small" type="chevron-down-icon"></li-icon> </button> <ul class="custom-header__dropdownlink-list--mobile hidden" data-dropdownlinks-list="true"> <li> <a href="https://www.linkedin.com/blog/engineering/machine-learning" class="t-sans t-black t-normal header-nav__link" target="_self">Machine Learning</a> </li> <li> <a href="https://www.linkedin.com/blog/engineering/natural-language-processing" class="t-sans t-black t-normal header-nav__link" target="_self">Natural Language Processing</a> </li> <li> <a href="https://www.linkedin.com/blog/engineering/generative-ai" class="t-sans t-black t-normal header-nav__link" target="_self">Generative AI</a> </li> <li> <a href="https://www.linkedin.com/blog/engineering/data-modeling" class="t-sans t-black t-normal header-nav__link" target="_self">Data Modeling</a> </li> <li> <a href="https://www.linkedin.com/blog/engineering/responsible-ai" class="t-sans t-black t-normal header-nav__link" target="_self">Responsible AI</a> </li> </ul> </li> <li class="custom-header__list-item--mobile" data-mobile-navigation-list-item="true"> <a href="https://www.linkedin.com/blog/engineering/trust-and-safety" class="t-16 t-sans t-black t-semibold header-nav__toplink" target="_self"> Trust &amp; Safety </a> <button class="header-navigation__button" aria-label="Expand to show more links for Trust &amp;amp; Safety" aria-expanded="false" data-mobile-dropdown-trigger type="button"> <li-icon size="small" type="chevron-down-icon"></li-icon> </button> <ul class="custom-header__dropdownlink-list--mobile hidden" data-dropdownlinks-list="true"> <li> <a href="https://www.linkedin.com/blog/engineering/fairness" class="t-sans t-black t-normal header-nav__link" target="_self">Fairness</a> </li> <li> <a href="https://www.linkedin.com/blog/engineering/verification" class="t-sans t-black t-normal header-nav__link" target="_self">Verification </a> </li> <li> <a href="https://www.linkedin.com/blog/engineering/security" class="t-sans t-black t-normal header-nav__link" target="_self">Security</a> </li> </ul> </li> <li class="custom-header__list-item--mobile" data-mobile-navigation-list-item="true"> <a href="https://www.linkedin.com/blog/engineering/product-design" class="t-16 t-sans t-black t-semibold header-nav__toplink" target="_self"> Product Design </a> <button class="header-navigation__button" aria-label="Expand to show more links for Product Design" aria-expanded="false" data-mobile-dropdown-trigger type="button"> <li-icon size="small" type="chevron-down-icon"></li-icon> </button> <ul class="custom-header__dropdownlink-list--mobile hidden" data-dropdownlinks-list="true"> <li> <a href="https://www.linkedin.com/blog/engineering/marketing" class="t-sans t-black t-normal header-nav__link" target="_self">Marketing </a> </li> <li> <a href="https://www.linkedin.com/blog/engineering/sales" class="t-sans t-black t-normal header-nav__link" target="_self">Sales</a> </li> <li> <a href="https://www.linkedin.com/blog/engineering/learning" class="t-sans t-black t-normal header-nav__link" target="_self">Learning</a> </li> <li> <a href="https://www.linkedin.com/blog/engineering/hiring" class="t-sans t-black t-normal header-nav__link" target="_self">Hiring</a> </li> <li> <a href="https://www.linkedin.com/blog/engineering/profile" class="t-sans t-black t-normal header-nav__link" target="_self">Profile</a> </li> <li> <a href="https://www.linkedin.com/blog/engineering/messaging-notifications" class="t-sans t-black t-normal header-nav__link" target="_self">Messaging/Notifications</a> </li> <li> <a href="https://www.linkedin.com/blog/engineering/feed" class="t-sans t-black t-normal header-nav__link" target="_self">Feed</a> </li> <li> <a href="https://www.linkedin.com/blog/engineering/profile" class="t-sans t-black t-normal header-nav__link" target="_self">Profile</a> </li> <li> <a href="https://www.linkedin.com/blog/engineering/groups" class="t-sans t-black t-normal header-nav__link" target="_self">Groups</a> </li> <li> <a href="https://www.linkedin.com/blog/engineering/accessibility" class="t-sans t-black t-normal header-nav__link" target="_self">Accessibility</a> </li> <li> <a href="https://www.linkedin.com/blog/engineering/member-customer-experience" class="t-sans t-black t-normal header-nav__link" target="_self">Member/Customer Experience</a> </li> <li> <a href="https://www.linkedin.com/blog/engineering/search" class="t-sans t-black t-normal header-nav__link" target="_self">Search</a> </li> <li> <a href="https://www.linkedin.com/blog/engineering/recommendations" class="t-sans t-black t-normal header-nav__link" target="_self">Recommendations</a> </li> <li> <a href="https://www.linkedin.com/blog/engineering/skills" class="t-sans t-black t-normal header-nav__link" target="_self">Skills</a> </li> </ul> </li> <li class="custom-header__list-item--mobile" data-mobile-navigation-list-item="true"> <a href="https://www.linkedin.com/blog/engineering/infrastructure" class="t-16 t-sans t-black t-semibold header-nav__toplink" target="_self"> Infrastructure </a> <button class="header-navigation__button" aria-label="Expand to show more links for Infrastructure" aria-expanded="false" data-mobile-dropdown-trigger type="button"> <li-icon size="small" type="chevron-down-icon"></li-icon> </button> <ul class="custom-header__dropdownlink-list--mobile hidden" data-dropdownlinks-list="true"> <li> <a href="https://www.linkedin.com/blog/engineering/code" class="t-sans t-black t-normal header-nav__link" target="_self">Code</a> </li> <li> <a href="https://www.linkedin.com/blog/engineering/scalability" class="t-sans t-black t-normal header-nav__link" target="_self">Scalability</a> </li> <li> <a href="https://www.linkedin.com/blog/engineering/distributed-systems" class="t-sans t-black t-normal header-nav__link" target="_self">Distributed Systems</a> </li> <li> <a href="https://www.linkedin.com/blog/engineering/graph-systems" class="t-sans t-black t-normal header-nav__link" target="_self">Graph Systems</a> </li> <li> <a href="https://www.linkedin.com/blog/engineering/architecture" class="t-sans t-black t-normal header-nav__link" target="_self">Architecture</a> </li> <li> <a href="https://www.linkedin.com/blog/engineering/analytics" class="t-sans t-black t-normal header-nav__link" target="_self">Analytics</a> </li> <li> <a href="https://www.linkedin.com/blog/engineering/automation" class="t-sans t-black t-normal header-nav__link" target="_self">Automation</a> </li> <li> <a href="https://www.linkedin.com/blog/engineering/platform-platformization" class="t-sans t-black t-normal header-nav__link" target="_self">Platforms/Platformization</a> </li> <li> <a href="https://www.linkedin.com/blog/engineering/cloud-computing" class="t-sans t-black t-normal header-nav__link" target="_self">Cloud Computing</a> </li> <li> <a href="https://www.linkedin.com/blog/engineering/open-source" class="t-sans t-black t-normal header-nav__link" target="_self">Open Source</a> </li> <li> <a href="https://www.linkedin.com/blog/engineering/additional-innovations" class="t-sans t-black t-normal header-nav__link" target="_self">Additional Innovations</a> </li> </ul> </li> <li class="custom-header__list-item--mobile" data-mobile-navigation-list-item="true"> <a href="https://www.linkedin.com/blog/engineering/talent" class="t-16 t-sans t-black t-semibold header-nav__toplink" target="_self"> Talent </a> <button class="header-navigation__button" aria-label="Expand to show more links for Talent" aria-expanded="false" data-mobile-dropdown-trigger type="button"> <li-icon size="small" type="chevron-down-icon"></li-icon> </button> <ul class="custom-header__dropdownlink-list--mobile hidden" data-dropdownlinks-list="true"> <li> <a href="https://www.linkedin.com/blog/engineering/culture" class="t-sans t-black t-normal header-nav__link" target="_self">Culture</a> </li> <li> <a href="https://www.linkedin.com/blog/engineering/developer-experience-productivity" class="t-sans t-black t-normal header-nav__link" target="_self">Developer Experience/Productivity</a> </li> <li> <a href="https://www.linkedin.com/blog/engineering/leadership" class="t-sans t-black t-normal header-nav__link" target="_self">Leadership</a> </li> </ul> </li> </ul> <div class="custom-header__button-share-container--mobile"> <!----> </div> </nav> </div> <main role="main"> <div id="lithograph-app"> <section id="component-container" data-attach-collapse-behavior="true"> <div id class="component component-articleHeadline" data-component-type="articleHeadline"> <div class="article-headline-container"> <p class="article-headline__topic"> <a class="t-14" href="https://www.linkedin.com/blog/engineering/analytics">Analytics</a> </p> <h1 class="article-headline t-40" data-article-title="GrafLI - An out-of-the-box Azure monitoring and visualization platform">GrafLI - An out-of-the-box Azure monitoring and visualization platform</h1> <div class="article-meta t-14 article-meta__hairline"> <div class="article-meta__byline-container"> <div class="author-profile__author-container"> <img class="author-profile__author-image" srcset="https://media.licdn.com/dms/image/v2/C5603AQH14pOcz0FYrQ/profile-displayphoto-shrink_100_100/profile-displayphoto-shrink_100_100/0/1593989707901?e=2147483647&amp;v=beta&amp;t=HNwl9RctI0vCwiOgOatbgIY41C_ozpU5hKCHA4aVSIY 100w,https://media.licdn.com/dms/image/v2/C5603AQH14pOcz0FYrQ/profile-displayphoto-shrink_200_200/profile-displayphoto-shrink_200_200/0/1593989707901?e=2147483647&amp;v=beta&amp;t=Q3DHMrT8X20vCUuU0ju-ePYJjMp1R_TvD6H1K37NUjE 200w,https://media.licdn.com/dms/image/v2/C5603AQH14pOcz0FYrQ/profile-displayphoto-shrink_400_400/profile-displayphoto-shrink_400_400/0/1593989707901?e=2147483647&amp;v=beta&amp;t=eHMnSGXD57Y_e5YXVnZqG2eWaqdfWeYqelHmKmId4T0 400w,https://media.licdn.com/dms/image/v2/C5603AQH14pOcz0FYrQ/profile-displayphoto-shrink_800_800/profile-displayphoto-shrink_800_800/0/1593989707901?e=2147483647&amp;v=beta&amp;t=TrpXlC0D0ErT9YbrKtk9f-euKtRnB8PyJv4RvY4gMzA 789w," sizes="(max-width: 480px) 480px, (max-width: 767px) 767px, (max-width: 1024px) 1024px, 1920px" src="https://media.licdn.com/dms/image/v2/C5603AQH14pOcz0FYrQ/profile-displayphoto-shrink_800_800/profile-displayphoto-shrink_800_800/0/1593989707901?e=2147483647&amp;v=beta&amp;t=TrpXlC0D0ErT9YbrKtk9f-euKtRnB8PyJv4RvY4gMzA" alt="Prateek Singh"> <div class="author-profile__author-text-container"> <a href="https://www.linkedin.com/in/prateekkumarsingh" target="_blank" class="t-14 t-bold"><span class="screen-reader">Authored by</span>Prateek Singh</a> <!----> <p class="t-14 t-black--light" data-published-date="2024-3-28"> March 28, 2024 </p> </div> </div> <!----> <div class="author-profile__co-authors-container"> <p> Co-authors: <!----> <a href="https://www.linkedin.com/in/prateekkumarsingh" target="_blank"><span class="screen-reader">Co-authored by</span>Prateek Singh</a><!----> and <a href="https://www.linkedin.com/in/errnair" target="_blank"><span class="screen-reader">Co-authored by</span>Rahul N.</a><!----> </p> </div> </div> <div class="social-share"> <ul class="social-share__list share-list" title="Share via" data-share-list> <li class="share-list__item share-item"> <a href="#" class="share-item__link medium-round-muted-tertiary-button" role="button" data-tracking-control-name="_linkedin_share" data-share-type="linkedin" aria-label="Share on LinkedIn, New window will open"> <li-icon class="share-item__icon" type="linkedin-icon"></li-icon> </a> </li> <li class="share-list__item share-item"> <a href="#" class="share-item__link medium-round-muted-tertiary-button" role="button" data-tracking-control-name="_facebook_share" data-share-type="facebook" aria-label="Share on Facebook, New window will open"> <li-icon class="share-item__icon" type="facebook-icon"></li-icon> </a> </li> <li class="share-list__item share-item"> <a href="#" class="share-item__link medium-round-muted-tertiary-button" role="button" data-tracking-control-name="_twitter_share" data-share-type="twitter" aria-label="Share on Twitter, New window will open"> <li-icon class="share-item__icon" type="twitter-icon"></li-icon> </a> </li> </ul> </div> </div> </div> </div> <div id class="component component-richText" data-component-type="richText"> <div class="rich-text global-paragraph-style--reader"> <p>In the ever-evolving landscape of cloud services, the importance of monitoring and visualizing data has become increasingly crucial for engineering organizations to enhance application performance, guarantee system reliability, ensure operational efficiency and enable strategic decision-making. At LinkedIn, the rapid expansion of the Azure footprint, coupled with the continuous addition of new services, necessitates a robust and scalable solution that can keep pace with the dynamic nature of cloud environments.<br> </p><p>Recognizing these challenges, the Productivity Engineering team at LinkedIn crafted GrafLI, a cloud-native data visualization tool designed to transform the visualization of Azure and on-premises services. In this post, we delve into the intricacies of GrafLI and how it enhances the developer experience and increases engineering velocity. We also talk about how GrafLI leverages Azure’s native monitoring stack and the powerful synergy of <a rel="" href="https://learn.microsoft.com/en-us/azure/governance/resource-graph/overview" target="_self">Azure Resource Graph</a>, <a rel="" href="https://learn.microsoft.com/en-us/azure/data-explorer/kusto/query/" target="_self">Kusto Query Language (KQL)</a> and <a rel="" href="https://learn.microsoft.com/en-us/azure/azure-monitor/overview" target="_self">Azure Monitor</a> to provide real-time visualization capabilities such as consolidated monitoring views, automated dynamic dashboard generation.</p><h2>Why GrafLI?<br> </h2><p>As the portfolio of applications and services hosted on Azure expanded within our organization, it was imperative that our internal monitoring capabilities evolved correspondingly. This encompassed all three fundamental pillars of monitoring: data collection, alerts, and visualization. Each of these components had to be scalable in order to meet our growing Azure footprint.<br> </p><p>Our earlier approaches involved manually curating metrics and creating visualizations using tools such as Log Analytics, Azure dashboards, and Grafana. These methods, while functional, posed significant challenges as we began implementing them at scale.<br> </p><p>As a result, we explored and implemented more automated and dynamic solutions for visualization. This led to us developing a custom layer on top of existing Azure monitoring components and leveraging native APIs to automate dashboard creation and updates. By enhancing our visualization capabilities, we created more efficient, real-time monitoring that met LinkedIn’s needs. It also improved our ability to respond to the evolving needs of our Azure-based applications and services.</p> </div> </div> <div id class="component component-standaloneImage" data-component-type="standaloneImage"> <div class="standalone-image-component standalone-image-component--article-width"> <figure> <img class="standalone-image-component__image" sizes="(max-width: 480px) 480px, (max-width: 767px) 767px, (max-width: 1024px) 1024px, 1920px" data-delayed-url="https://media.licdn.com/dms/image/v2/D4D08AQGe2EvTjlVkTA/croft-frontend-shrinkToFit1024/croft-frontend-shrinkToFit1024/0/1711550103667?e=2147483647&amp;v=beta&amp;t=g0BXYS3S9WZ2VO0iaQaCTLt58Nwzke-I5ydhOO1oxYA" alt="Image of the benefits of GrafLI"> <figcaption class="t-16 t-black--light standalone-image-component__caption">Figure 1. Benefits of GrafLI's unified monitoring and visualization ecosystem</figcaption> </figure> </div> </div> <div id class="component component-richText" data-component-type="richText"> <div class="rich-text global-paragraph-style--reader"> <h2>Key features of GrafLI</h2><h3>Out-of-the-box visualizations<br> </h3><p>GrafLI’s primary feature is the dynamic dashboard generation that enables effortless scaling of visualizations for various services or environments. This eliminates the need to manually monitor dashboard creation and ensures instant visualizations for any provisioned application, workload, or service in Azure. Leveraging the power of CI/CD and Infrastructure as Code (IaC) provisioning pipelines, GrafLI significantly reduces time-to-value (TTV) by efficiently provisioning Azure monitoring infrastructure and establishing monitoring data ingestion with pre-defined baselines.&nbsp;<br> </p><h3>Discoverability and ease of search<br> </h3><p>GrafLI significantly enhances the developer experience by making it easier to search and access visualizations. By utilizing optimized Azure Resource Graph queries, which guarantees scalability and rapid compilation of all Azure-provisioned applications, GrafLi allows users to access a complete and up-to-date list of their deployed Azure resources in a matter of seconds. Consequently, developers can quickly explore the relevant metrics for their Azure resources, leading to a more efficient and productive workflow. </p> </div> </div> <div id class="component component-standaloneImage" data-component-type="standaloneImage"> <div class="standalone-image-component standalone-image-component--article-width"> <figure> <img class="standalone-image-component__image" sizes="(max-width: 480px) 480px, (max-width: 767px) 767px, (max-width: 1024px) 1024px, 1920px" data-delayed-url="https://media.licdn.com/dms/image/v2/D4D08AQF1PIPnRYSwpg/croft-frontend-shrinkToFit1024/croft-frontend-shrinkToFit1024/0/1711550371433?e=2147483647&amp;v=beta&amp;t=UGDVtsY94rJG2-w2tIxsTPsKnVIEe_h4RxjuzNpz56o" alt="Image of GrafLI’s user view of Application Search"> <figcaption class="t-16 t-black--light standalone-image-component__caption">Figure 2.1. GrafLI’s user view - Application Search</figcaption> </figure> </div> </div> <div id class="component component-richText" data-component-type="richText"> <div class="rich-text global-paragraph-style--reader"> <h3>Consolidated monitoring dashboards<br> </h3><p>GrafLI seamlessly compiles metrics from diverse sources to present a unified dashboard for comprehensive observability across entire application stacks. This user-friendly dashboard combines different statuses, metrics, trends, and statistics from application facets and dimensions. These encompass elements like user interactions, server response times, dependencies, exceptions, custom events, and other relevant aspects.<br> </p><p>GrafLI also provides more focused insights through drill-downs into Application Performance Metrics (APM), Infrastructure Metrics (IaaS), and Platform Metrics (PaaS) for a more nuanced analysis and understanding of application behavior and performance.</p> </div> </div> <div id class="component component-standaloneImage" data-component-type="standaloneImage"> <div class="standalone-image-component standalone-image-component--article-width"> <figure> <img class="standalone-image-component__image" sizes="(max-width: 480px) 480px, (max-width: 767px) 767px, (max-width: 1024px) 1024px, 1920px" data-delayed-url="https://media.licdn.com/dms/image/v2/D4D08AQFMbx0622Mh7A/croft-frontend-shrinkToFit1024/croft-frontend-shrinkToFit1024/0/1711550462603?e=2147483647&amp;v=beta&amp;t=NmIa8R-2O4DyajbcX5zXf2FT6j7VXtpGmoCFihz_0KU" alt="Image of GrafLI’s user view for the Application Overview"> <figcaption class="t-16 t-black--light standalone-image-component__caption">Figure 2.2. GrafLI’s user view - Application Overview</figcaption> </figure> </div> </div> <div id class="component component-richText" data-component-type="richText"> <div class="rich-text global-paragraph-style--reader"> <h2>How it works<br> </h2><p>Over the next few sections, we will cover the different segments of GrafLI and how it comes together to provide a single unified monitoring, metrics collection, and visualization platform.</p><h3>Architecture</h3><p>Let’s start by taking a high-level look into the intricacies of GrafLI's architecture and service ecosystem from the users’ perspective and their interactions with Azure.</p> </div> </div> <div id class="component component-standaloneImage" data-component-type="standaloneImage"> <div class="standalone-image-component standalone-image-component--article-width"> <figure> <img class="standalone-image-component__image" sizes="(max-width: 480px) 480px, (max-width: 767px) 767px, (max-width: 1024px) 1024px, 1920px" data-delayed-url="https://media.licdn.com/dms/image/v2/D4D08AQFaJjURcPA_qQ/croft-frontend-shrinkToFit1024/croft-frontend-shrinkToFit1024/0/1711550670620?e=2147483647&amp;v=beta&amp;t=1DlIDRLe8YWFgQDub5klDc_sXoWYa8_F3uu7wk14jFQ" alt="Image of GrafLI’s high-level design"> <figcaption class="t-16 t-black--light standalone-image-component__caption">Figure 3.1. GrafLI’s high-level design</figcaption> </figure> </div> </div> <div id class="component component-richText" data-component-type="richText"> <div class="rich-text global-paragraph-style--reader"> <p>A user’s journey begins when they commit their infrastructure deployment code to our IaC repositories (Azure DevOps or GitHub). This action triggers the Azure CI/CD pipelines, which kickstarts the infrastructure provisioning process that includes foundational deployments such as networking and monitoring, along with the deployment of requested resources specified in the Infrastructure as Code (IaC) code. These resources can range from building VMs to App services or any Platform as a Service (PaaS) components (such as Azure Functions, CosmosDB and more), ensuring strict adherence to security principles, naming conventions, and resource tagging with metadata like owners and departments.<br> </p><p>Once the resources are provisioned, the user or the application owner accesses the GrafLI web application. When a user accesses the GrafLI’s web application, the request triggers several backend API endpoints via the Azure WebApp service. The backend analyzes resource deployment patterns, aggregates relevant metrics from multiple Azure sources, and delivers them to the web frontend in the form of time-series data.</p><p>Finally, the frontend transforms this time series data into graphs and visualizations within a single dashboard, serving it to the client's browser for a comprehensive monitoring experience.</p><h3>Infrastructure provisioning, log ingestion and monitoring strategy<br> </h3><h4>Infrastructure as Code (IaC)</h4><p>With cloud providers like Azure, infrastructure provisioning pipelines play a crucial role in ensuring consistency across deployed resources. This entails following standardized patterns, including naming conventions, Azure resource tags, location, SKU, and resource group specifications.<br> </p><p>Let’s explore how adhering to these established patterns and conventions effectively streamlines the discoverability of related resources at scale within Azure.<br> </p><h4>Establishing a Monitoring Baseline</h4><p>Azure infrastructure provisioners seamlessly allows us to use different baseline configurations during deployments via <a rel="" href="https://learn.microsoft.com/en-us/azure/azure-resource-manager/templates/" target="_self">ARM template deployments</a>. From a monitoring and visualization perspective, this translates to:<br> </p><ul><li><strong>Installing Monitoring Agents</strong>: Ensuring the essential agents (<a rel="" href="https://learn.microsoft.com/en-us/azure/azure-monitor/agents/agents-overview" target="_self">Azure Monitor agent</a>, <a rel="" href="https://learn.microsoft.com/en-us/azure/azure-monitor/agents/log-analytics-agent" target="_self">Log Analytics agent</a>, etc.) are in place for effective monitoring.</li><li><strong>Enabling Performance Counters:</strong> Activating performance counters to gauge system performance efficiently on <a rel="" href="https://azure.microsoft.com/en-in/solutions/azure-iaas/" target="_self">Azure IaaS</a> (Virtual Machines, Virtual Machine Scale Sets, etc.).</li><li><strong>Installing Monitoring Solutions:</strong> Deploying specialized monitoring solutions tailored to specific needs, like <a rel="" href="https://learn.microsoft.com/en-us/azure/automation/change-tracking/enable-from-portal#enable-change-tracking-and-inventory" target="_self">Change Tracking</a>, <a rel="" href="https://learn.microsoft.com/en-us/azure/azure-monitor/vm/vminsights-enable-resource-manager" target="_self">VM Insights</a>, Service Map, etc.</li><li><strong>Enabling Diagnostic Settings:</strong> Configuring <a rel="" href="https://learn.microsoft.com/en-us/azure/azure-monitor/essentials/create-diagnostic-settings?tabs=portal" target="_self">diagnostic settings</a> for enhanced insights into behavior of <a rel="" href="https://azure.microsoft.com/en-in/resources/cloud-computing-dictionary/what-is-paas" target="_self">Azure PaaS</a> components and to converge logs to a centralized Azure Monitor logs.</li><li><strong>Configure Alerts and thresholds</strong>: Establish and customize alert configurations, defining baseline thresholds for optimal performance in the Azure environment.</li></ul><p>By combining standard IaC principles with robust monitoring baselines, our approach ensures consistent infrastructure and enables us to proactively set up a comprehensive monitoring system during the provisioning process that provides visibility of all the services deployed in Azure. Once the relevant Azure components are deployed, the next steps involve developing a system that queries the logs and metrics from Azure, at scale.<br> </p><h3>Querying logs &amp; metrics at scale&nbsp;</h3><p>When users search for a specific application or service, the Azure Resource Graph yields a list of potential matches. When the user makes a selection, GrafLI precisely identifies the Azure Monitor resource associated with the chosen workload, and queries the logs and metrics that are typically routed to Azure Application Insights or the Log Analytics workspaces.</p><h4>Azure Resource Graph</h4><p>With GrafLI, the ability to query at scale has been a game-changer. <a rel="" href="https://learn.microsoft.com/en-us/azure/governance/resource-graph/" target="_self">Azure Resource Graph</a> plays a vital role in facilitating this by simplifying the process of gathering a comprehensive list of provisioned resources. This includes monitoring resources, tenants, and tags, and relevant resource ownership information. This capability is important to GrafLI because it helps precisely targeting monitoring resources such as Azure Log Analytics and Azure Application Insights to retrieve the relevant logs and metrics associated with deployed infrastructure and/or applications.</p><p>In addition to leveraging the power of Azure Resource Graph, GrafLI also allows users to effortlessly discover alerts and various resource types through resource graph queries. Applications and deployed infrastructure are automatically on-boarded onto the Azure Monitoring stack as soon as an application becomes discoverable within Azure Resource Graph, enhancing the efficiency of the entire monitoring process.<br> </p><h4>Kusto Query Language (KQL)</h4><p>To gather monitoring information and other metrics, GrafLI heavily relies on the <a rel="" href="https://learn.microsoft.com/en-us/azure/data-explorer/kusto/query/" target="_self">Kusto Query Language (KQL)</a>. We execute a series of predefined query templates crafted in KQL, targeting both the Log Analytics workspace and Application Insights. An example for this is listed below:<br> </p> </div> </div> <div class="component component-codeBlock" data-component-type="codeBlock"> <div class="codeblock" data-code-block> <div class="codeblock__language"> Python </div> <div class="codeblock__snippet"> <pre><code class="language-python"> { "cpu": """let interval = {0}m; let stime = datetime({1}); let etime = datetime({2}); InsightsMetrics | where Name contains "UtilizationPercentage" and Computer contains '{3}' | make-series Cpu = toint(avg(Val)) on TimeGenerated from stime to etime step interval by Computer""", "mem": """let interval = {0}m; let stime = datetime({1}); let etime = datetime({2}); InsightsMetrics | where Namespace contains "Memory" and Name contains "AvailableMB" and Computer contains '{3}' | make-series Mem = (100 - toint(avg((Val/toint(parse_json(Tags["vm.azm.ms/memorySizeMB"])*100)))) on TimeGenerated from stime to etime step interval by Computer""", "disk": """let interval = {0}m; let stime = datetime({1}); let etime = datetime({2}); InsightsMetrics | where Namespace contains "LogicalDisk" and Name contains "FreeSpacePercentage" and Computer contains '{3}' | make-series Disk = (100 - toint(avg(Val))) on TimeGenerated from stime to etime step interval by Compute""" }</code></pre> </div> </div> </div> <div id class="component component-richText" data-component-type="richText"> <div class="rich-text global-paragraph-style--reader"> <h4>Batch queries<br> </h4><p>The <a rel="" href="https://learn.microsoft.com/en-us/azure/azure-monitor/logs/api/batch-queries" target="_self">Azure Monitor Log Analytics API</a> and <a rel="" href="https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/monitor/azure-monitor-query/samples/sample_batch_query.py" target="_self">Query Client SDK</a> both provide a compelling feature of batching queries together. This enhancement not only elevates the efficiency of our querying processes but also brings noteworthy advantages when dealing with querying multiple logs and metrics for a consolidated single pane of glass.<br> </p><h4>Cross resource queries<br> </h4><p>When dealing with a diverse range of resources and monitoring elements in a complex cloud setup, it's important to fetch monitoring data seamlessly at scale. <a rel="" href="https://learn.microsoft.com/en-us/azure/azure-monitor/logs/cross-workspace-query" target="_self">Cross-Resource Queries</a> within the Log Analytics workspace allows us to easily specify the workspace, app, or resource details using expressions like <a rel="" href="https://learn.microsoft.com/en-us/azure/azure-monitor/logs/cross-workspace-query#query-across-log-analytics-workspaces-using-workspace" target="_self">workspace()</a>, <a rel="" href="https://learn.microsoft.com/en-us/azure/azure-monitor/logs/cross-workspace-query#query-across-classic-application-insights-applications-using-app" target="_self">app()</a>, or <a rel="" href="https://learn.microsoft.com/en-us/azure/azure-monitor/logs/cross-workspace-query#correlate-data-between-resources-using-resource" target="_self">resource()</a> expressions.<br> </p><p>Next, we’ll delve into how the metrics collected using these mechanisms are aggregated and visualized.</p><h3>Metric aggregation and time-series data delivery<br> </h3><p>In GrafLI, we harness the power of the <a rel="" href="https://pypi.org/project/azure-monitor-query/" target="_self">Azure Monitor Query client library</a> to seamlessly execute read-only queries across Azure Monitor's dual <a rel="" href="https://learn.microsoft.com/en-gb/azure/azure-monitor/data-platform" target="_self">data platform</a>:<br> </p><ul><li><strong>Logs: </strong>Our system methodically gathers and organizes logs and performance data from diverse sources, including platform logs from Azure services, performance data from virtual machine agents, and usage statistics from applications. This data is normalized and available within a unified <a rel="" href="https://learn.microsoft.com/azure/azure-monitor/logs/data-platform-logs#log-analytics-and-workspaces" target="_self">Azure Log Analytics workspace</a>. Leveraging the Kusto Query Language, various data types (like datetime, string, integer, decimals, etc.) can be comprehensively analyzed together, enhancing the depth and efficiency of our monitoring capabilities.<br> </li><li><strong>Metrics: </strong>GrafLI leverages <a rel="" href="https://learn.microsoft.com/en-us/rest/api/monitor/metric-definitions/list?view=rest-monitor-2018-01-01&tabs=HTTP" target="_self">Azure Metric definitions</a> to discover metrics for Azure Platform as a Service (PaaS) resources. These definitions include a description, unit, aggregations, time granularities etc as shown in the following figure:<br> </li></ul> </div> </div> <div id class="component component-standaloneImage" data-component-type="standaloneImage"> <div class="standalone-image-component standalone-image-component--article-width"> <figure> <img class="standalone-image-component__image" sizes="(max-width: 480px) 480px, (max-width: 767px) 767px, (max-width: 1024px) 1024px, 1920px" data-delayed-url="https://media.licdn.com/dms/image/v2/D4D08AQFU5l5xK-OgCg/croft-frontend-shrinkToFit1024/croft-frontend-shrinkToFit1024/0/1711551407130?e=2147483647&amp;v=beta&amp;t=a6U1-mEh27QnN9dfi1tAevJh2kHF3l3qOFK6iQUNGB0" alt="Image of Metrics Definitions"> <figcaption class="t-16 t-black--light standalone-image-component__caption">Figure 3.2. Metrics Definitions</figcaption> </figure> </div> </div> <div id class="component component-richText" data-component-type="richText"> <div class="rich-text global-paragraph-style--reader"> <p class="ql-indent-1">This process involves utilizing the query client library to identify and <a rel="" href="https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/monitor/azure-monitor-query/samples/sample_metric_definitions.py" target="_self">retrieve metric definitions</a>, allowing GrafLI to offer comprehensive insights into the performance and health of Azure PaaS resources.&nbsp;<br> </p><p>Once we pinpoint the target monitoring resource, and the query is executed, the resultant monitoring data is presented in the form of a time series dataset. The user interface facilitates the application of aggregations to this data, enhancing the depth and precision of the insights derived from the monitoring process based on time granularity and range. <br> </p> </div> </div> <div id class="component component-standaloneImage" data-component-type="standaloneImage"> <div class="standalone-image-component standalone-image-component--article-width"> <figure> <img class="standalone-image-component__image" sizes="(max-width: 480px) 480px, (max-width: 767px) 767px, (max-width: 1024px) 1024px, 1920px" data-delayed-url="https://media.licdn.com/dms/image/v2/D4D08AQElVdVIwGlYVg/croft-frontend-shrinkToFit1024/croft-frontend-shrinkToFit1024/0/1711551654091?e=2147483647&amp;v=beta&amp;t=03H7WzBXTpsiESZbrq8giF3iMux6aegfi9EFYmrbXtg" alt="Image of Time Series data"> <figcaption class="t-16 t-black--light standalone-image-component__caption">Figure 3.3. Time-series data</figcaption> </figure> </div> </div> <div id class="component component-richText" data-component-type="richText"> <div class="rich-text global-paragraph-style--reader"> <h3>Charting and visualizations<br> </h3><p>Utilizing the time-series datasets and the metric definitions retrieved from Azure Monitor, GrafLI employs advanced charting and visualization libraries like <a rel="" href="https://www.chartjs.org/" target="_self">ChartJS</a> and <a rel="" href="https://d3js.org/" target="_self">D3.js</a> to dynamically generate compelling visualizations in real-time. This seamless integration of data visualization provides users with an intuitive and insightful monitoring experience as soon as the application or the Azure resource is deployed.</p> </div> </div> <div id class="component component-standaloneImage" data-component-type="standaloneImage"> <div class="standalone-image-component standalone-image-component--article-width"> <figure> <img class="standalone-image-component__image" sizes="(max-width: 480px) 480px, (max-width: 767px) 767px, (max-width: 1024px) 1024px, 1920px" data-delayed-url="https://media.licdn.com/dms/image/v2/D4D08AQGXdUO5rmxD8Q/croft-frontend-shrinkToFit1024/croft-frontend-shrinkToFit1024/0/1711551899799?e=2147483647&amp;v=beta&amp;t=_LTSok80DoAfJWWnNwOSMwessZ219GeG60EbYGW8qes" alt="Image of Metrics visualization on chart "> <figcaption class="t-16 t-black--light standalone-image-component__caption">Figure 3.4. Metrics visualization on chart </figcaption> </figure> </div> </div> <div id class="component component-standaloneImage" data-component-type="standaloneImage"> <div class="standalone-image-component standalone-image-component--article-width"> <figure> <img class="standalone-image-component__image" sizes="(max-width: 480px) 480px, (max-width: 767px) 767px, (max-width: 1024px) 1024px, 1920px" data-delayed-url="https://media.licdn.com/dms/image/v2/D4D08AQHlQzqXb8GQCw/croft-frontend-shrinkToFit1024/croft-frontend-shrinkToFit1024/0/1711552026148?e=2147483647&amp;v=beta&amp;t=3Q0qtridnTAtreVqlI1G0P-iWTtpSTjZHXqjTPvBhQI" alt="Image of Metrics visualization on chart"> <figcaption class="t-16 t-black--light standalone-image-component__caption">Figure 3.5. Metrics visualization on chart</figcaption> </figure> </div> </div> <div id class="component component-richText" data-component-type="richText"> <div class="rich-text global-paragraph-style--reader"> <p>Visualizations in GrafLI are classified into four primary categories:<br> </p><ol><li>Service Overview</li><li>Infrastructure Metrics (IaaS)</li><li>Platform Metrics (PaaS)</li><li>Application Performance Metrics (APM)</li></ol><h4>Service overview<br> </h4><p>This view provides users with a high-level summary, collating critical information about application availability, performance, infrastructure metrics, and platform-specific metrics. The visualizations here serve as a gateway to delve deeper into the nuances of the monitored components.</p> </div> </div> <div id class="component component-standaloneImage" data-component-type="standaloneImage"> <div class="standalone-image-component standalone-image-component--article-width"> <figure> <img class="standalone-image-component__image" sizes="(max-width: 480px) 480px, (max-width: 767px) 767px, (max-width: 1024px) 1024px, 1920px" data-delayed-url="https://media.licdn.com/dms/image/v2/D4D08AQEt1TEAHY76bA/croft-frontend-shrinkToFit1024/croft-frontend-shrinkToFit1024/0/1711552228307?e=2147483647&amp;v=beta&amp;t=nKCv94RuXdcJa5CJJS3iJ_-pMrluPTcr9nCZHK9mvFM" alt="Image of GrafLI user view - Application overview"> <figcaption class="t-16 t-black--light standalone-image-component__caption">Figure 3.6. GrafLI user view - Application overview</figcaption> </figure> </div> </div> <div id class="component component-richText" data-component-type="richText"> <div class="rich-text global-paragraph-style--reader"> <h4>Infrastructure (IaaS) metrics<br> </h4><p>In this view, GrafLI focuses on Infrastructure as a Service (IaaS) metrics, offering detailed insights into the performance and health of the underlying infrastructure components, mostly Virtual Machines and Virtual Machine Scale sets. Users can easily track and visualize key resource indicators like CPU, Memory and Disk Utilization enabling proactive measures and ensuring the seamless operation of the infrastructure deployed on Azure or on-premises.</p> </div> </div> <div id class="component component-standaloneImage" data-component-type="standaloneImage"> <div class="standalone-image-component standalone-image-component--article-width"> <figure> <img class="standalone-image-component__image" sizes="(max-width: 480px) 480px, (max-width: 767px) 767px, (max-width: 1024px) 1024px, 1920px" data-delayed-url="https://media.licdn.com/dms/image/v2/D4D08AQHpWyuftEOIpA/croft-frontend-shrinkToFit1024/croft-frontend-shrinkToFit1024/0/1711552655031?e=2147483647&amp;v=beta&amp;t=DgWcFTS7AOxNYcs0VA47P5DTKhTiuCycWMmwwykDeuQ" alt="Image of GrafLI user view - Infrastructure overview"> <figcaption class="t-16 t-black--light standalone-image-component__caption">Figure 3.7. GrafLI user view - Infrastructure overview</figcaption> </figure> </div> </div> <div id class="component component-richText" data-component-type="richText"> <div class="rich-text global-paragraph-style--reader"> <h4>Application Performance Metrics (APM)<br> </h4><p>With the APM view, GrafLI offers granular insights into Application Performance Metrics (APM), giving users a detailed understanding of their applications' performance. This section delves into response times, error rates, and other crucial APM metrics, allowing engineering teams to pinpoint issues promptly and optimize application performance for an enhanced end-user experience.</p> </div> </div> <div id class="component component-standaloneImage" data-component-type="standaloneImage"> <div class="standalone-image-component standalone-image-component--article-width"> <figure> <img class="standalone-image-component__image" sizes="(max-width: 480px) 480px, (max-width: 767px) 767px, (max-width: 1024px) 1024px, 1920px" data-delayed-url="https://media.licdn.com/dms/image/v2/D4D08AQG4dGrjRMEE5A/croft-frontend-shrinkToFit1024/croft-frontend-shrinkToFit1024/0/1711552781710?e=2147483647&amp;v=beta&amp;t=Di6UQXnwfOlFB4_aXGFJXA5bS7r6ZGtF9wqcOJPkiHo" alt="Image of GrafLI user view - Application Performance"> <figcaption class="t-16 t-black--light standalone-image-component__caption">Figure 3.8. GrafLI user view - Application Performance</figcaption> </figure> </div> </div> <div id class="component component-richText" data-component-type="richText"> <div class="rich-text global-paragraph-style--reader"> <h4>Platform Metrics (PaaS)<br> </h4><p>The Platform Metrics section is dedicated to providing visibility into the performance of Platform as a Service (PaaS) components. GrafLI captures and visualizes critical metrics related to Azure's PaaS offerings, allowing users to monitor the health of these services, ultimately ensuring the seamless functioning of cloud-based applications.</p> </div> </div> <div id class="component component-standaloneImage" data-component-type="standaloneImage"> <div class="standalone-image-component standalone-image-component--article-width"> <figure> <img class="standalone-image-component__image" sizes="(max-width: 480px) 480px, (max-width: 767px) 767px, (max-width: 1024px) 1024px, 1920px" data-delayed-url="https://media.licdn.com/dms/image/v2/D4D08AQHkeB0UlAbkRA/croft-frontend-shrinkToFit1024/croft-frontend-shrinkToFit1024/0/1711552902531?e=2147483647&amp;v=beta&amp;t=NJGO4xGB835h9kXWKLqMmfRKCH3_kfQ0ad28UFKXc_8" alt="Image of GrafLI user view - Platform overview"> <figcaption class="t-16 t-black--light standalone-image-component__caption">Figure 3.9. GrafLI user view - Platform overview</figcaption> </figure> </div> </div> <div id class="component component-richText" data-component-type="richText"> <div class="rich-text global-paragraph-style--reader"> <p>By leveraging these meticulously curated views within GrafLI, engineering teams gain a comprehensive understanding of their Azure environment. The dynamic visualizations, powered by ChartJS and D3.js, transform raw data into actionable insights, empowering teams and application owners to make informed decisions using these consolidated monitoring dashboards.</p><h3>GrafLI’s extensible framework<br> </h3><p>While building GrafLI, we prioritized extensibility and adaptability to accommodate changes seamlessly. This design ethos facilitates the onboarding of applications beyond the Azure ecosystem. Additionally, it empowers users to collect metrics through custom KQL queries, expanding the GrafLI’s capabilities beyond the limitations of standard Azure queries.</p><h4>Hybrid and on-premises workloads<strong><br> </strong></h4><p>GrafLI relies on Azure resource deployment patterns accessed through Resource Graph. However, onboarding applications and resources deployed on our on-premise data centers, running on virtualization platforms and applications involves provisioning Azure Log Analytics and Application Insights, maintaining a specific naming convention, and configuring monitoring agents. This allows for GrafLI’s seamless integration with on-premise workloads. <br> </p><p>In LinkedIn’s software ecosystem, which are organized into releasable logical units known as <a rel="" href="https://engineering.linkedin.com/blog/2017/01/great-tools-for-engineers--refactoring-across-multiple-code-repo" target="_self">'multiproducts</a>', onboarding to GrafLI is facilitated by provisioning essential Azure monitoring resources and implementing <a rel="" href="https://learn.microsoft.com/en-us/azure/azure-monitor/app/javascript-sdk?tabs=javascriptwebsdkloaderscript" target="_self">code-based instrumentation using the Azure SDK</a> which allows applications to send app telemetry to Azure Application Insights. Upon populating metrics within the Azure monitor resource, GrafLI can swiftly generate dashboards and visualizations, providing instant insights.<br> </p><h4>Customizing metrics: a tailored query approach<strong><br> </strong></h4><p>GrafLI goes beyond the constraints of predefined <a rel="" href="https://learn.microsoft.com/en-us/rest/api/monitor/metric-definitions/list?view=rest-monitor-2018-01-01&tabs=HTTP" target="_self">Azure Resource metric definitions</a>, providing users with the flexibility to extend support for custom metrics to support the monitoring requirements unique to their service, application, or team. <br> </p><p>By seamlessly onboarding a templatized KQL query that accommodates time range and granularity specifications, this approach facilitates the rapid onboarding of virtually any metric. Whether it's <a rel="" href="https://learn.microsoft.com/en-us/azure/azure-monitor/agents/data-sources-custom-logs" target="_self">custom text-based logs</a> or sophisticated queries on existing logs, this versatile capability allows users to quickly integrate diverse metrics within minutes, and scale to practically any application or service onboarded to GrafLI.<br> </p><p>The following are a few samples of templated custom queries designed to retrieve time series data:</p> </div> </div> <div class="component component-codeBlock" data-component-type="codeBlock"> <div class="codeblock" data-code-block> <div class="codeblock__language"> Python </div> <div class="codeblock__snippet"> <pre><code class="language-python">{ "requests/http_status_code": """let interval = {0}m; let stime = datetime({1}); let etime = datetime({2}); let Custom = app('{3}').requests; Custom | where client_Type != "Browser" | make-series ['requests/http_status_code']= sum(itemCount) on timestamp from stime to etime step interval by resultCode """, "pageViews/browser": """let interval = {0}m; let stime = datetime({1}); let etime = datetime({2}); let Custom = app('{3}').pageViews; Custom | extend browser = replace(@'(.\d+)','',client_Browser) | make-series ['pageViews/browser']= count(user_Id) on timestamp from stime to etime step interval by browser""", "pageViews/device_model": """let interval = {0}m; let stime = datetime({1}); let etime = datetime({2}); let Custom = app('{3}').pageViews; Custom | make-series ['pageViews/device_model' = count(user_Id) on timestamp from stime to etime step interval by client_Model""", } </code></pre> </div> </div> </div> <div id class="component component-richText" data-component-type="richText"> <div class="rich-text global-paragraph-style--reader"> <h3>Metrics &amp; Impact<br> </h3><p>As GrafLI went live, we also found that it significantly enhances developer productivity by providing a multifaceted view of both Azure and hybrid environments through its advanced visualization capabilities. GrafLI transforms complex time-series data into clear, real-time visualizations across multiple dimensions: service overview, IaaS, APM, and PaaS metrics. This allows developers and on-call engineers to quickly analyze application performance, infrastructure health, and platform efficiency.&nbsp;<br> </p><p>GrafLI not only boosts developer productivity but also facilitates improved resource utilization and swifter responses to monitoring requirements. This results in tangible cost savings and heightened operational efficiency.</p><h4>Coverage<br> </h4><p>GrafLI encompasses a total of 1500+ dashboards, each spanning 800+ distinct services deployed in Azure. Access to approximately ~100K Azure resources and their corresponding metrics, including both Infrastructure as a Service (IaaS) and Platform as a Service (PaaS) components, along with their metric definitions.</p> </div> </div> <div id class="component component-standaloneImage" data-component-type="standaloneImage"> <div class="standalone-image-component standalone-image-component--article-width"> <figure> <img class="standalone-image-component__image" sizes="(max-width: 480px) 480px, (max-width: 767px) 767px, (max-width: 1024px) 1024px, 1920px" data-delayed-url="https://media.licdn.com/dms/image/v2/D4D08AQFLcA6QODh21w/croft-frontend-shrinkToFit1024/croft-frontend-shrinkToFit1024/0/1711553796005?e=2147483647&amp;v=beta&amp;t=8mJSqHIhsfXPxLVAQQ2QSrQZkhkEes5f58h_xD9MlSQ" alt="Image of GrafLI services"> <figcaption class="t-16 t-black--light standalone-image-component__caption">Figure 4. GrafLI services</figcaption> </figure> </div> </div> <div id class="component component-richText" data-component-type="richText"> <div class="rich-text global-paragraph-style--reader"> <h4>Efficiency in Insights<br> </h4><p>Users experience a notable reduction in the time needed to access insights. Time to insights is slashed from minutes to seconds, fostering quicker decision-making and heightened productivity.</p><h2>Conclusion and Future Work<br> </h2><p>The task of effectively monitoring and visualizing metrics within the dynamically changing environment of cloud, hybrid and containerized workloads poses a significant challenge to modern organizations. GrafLI, is a turnkey solution that aims to solve a lot of these complexities by building on top of the Azure Monitoring Stack and unifying the monitoring, metrics collection and visualization challenges in a holistic manner.&nbsp;<br> </p><p>Since it was operationalized, GrafLI has offered automated monitoring dashboards, enhanced search and discoverability features, with ability to integrate metrics from a variety of sources to hundreds of applications deployed on Azure. We aim to expand on this implementation by adding capabilities to monitor and visualize hybrid, and containerized workloads, making GrafLI the de-facto visualization platform for LinkedIn’s Productivity Engineering team.&nbsp;<br> </p><p>Our focus remains on providing a robust, efficient, and comprehensive visualization solution that keeps pace with the ever-changing technological landscape.</p><h2>Acknowledgements</h2><p>Thanks to the team: <a rel="" href="https://www.linkedin.com/in/raghavayyamani/" target="_self">Raghav Ayyamani</a>, and <a rel="" href="https://www.linkedin.com/in/m-bhandari/" target="_self">Madhav Bhandari</a> for making this project possible and contributing to the project from ideation through design, and implementation. Our gratitude also extends to our leaders, <a rel="" href="https://www.linkedin.com/in/balajiramswamy/" target="_self">Balaji Ramaswamy</a>, <a rel="" href="https://www.linkedin.com/in/balajivappala/" target="_self">Balaji Vappala</a>, and <a rel="" href="https://www.linkedin.com/in/harihara-sudhan/" target="_self">Harihara Sudhan</a> for providing the opportunity, continuous encouragement, and invaluable guidance throughout this endeavor. A special note of thanks to <a rel="" href="https://www.linkedin.com/in/sudha-p/" target="_self">Sudha Prabhunandan</a> for her valuable mentorship, continuous feedback from inception to implementation, and assistance in driving product adoption.</p> </div> </div> <div id class="component component-postList" data-component-type="postList"> <section id="postList0FocusPoint" class="component__content-container list-layout" data-post-list> <!----> <!----> <section class="list-layout__headline-container"> <p class="list-layout__headline t-32 t-sans">Related articles</p> <!----> </section> <ul class="list-layout__posts"> <li class="post-list__item list-post"> <div class="list-post__content-container"> <p class="list-post__content-container__topic"> <a class="t-14 t-bold" href="https://www.linkedin.com/blog/engineering/infrastructure"> Infrastructure </a> </p> <div class="list-post__content-container__title"> <a class="list-post__link t-20 t-black" href="https://www.linkedin.com/blog/engineering/infrastructure/stateful-workload-operator-stateful-systems-on-kubernetes-at-linkedin"> Stateful workload operator: stateful systems on Kubernetes at ... </a> </div> <div class="list-post__content-container__byline"> <p class="list-post__content-container__author t-14 t-bold t-black"> Michael Youssef </p> <!----><!----> <p class="list-post__content-container__date t-14 t-black--light"> Nov 12, 2024 </p> </div> </div> <div class="list-post__image-container"> <figure class="post__image-figure"> <img class="post__image" data-delayed-url="https://media.licdn.com/dms/image/v2/D4D08AQEAvd2TbRyUIA/croft-frontend-shrinkToFit1024/croft-frontend-shrinkToFit1024/0/1731085364122?e=2147483647&amp;v=beta&amp;t=NZXz21rCecWKdjseUzG6q9gnjJLyckxl1aiA9siKWHc" data-ghost-url="https://static.licdn.com/aero-v1/sc/h/8pouyb1ly746xtru0x7p2axm0" sizes="(max-width: 480px) 480px, (max-width: 767px) 767px, (max-width: 1024px) 1024px, 480px"> </figure> </div> </li> <li class="post-list__item list-post"> <div class="list-post__content-container"> <p class="list-post__content-container__topic"> <a class="t-14 t-bold" href="https://www.linkedin.com/blog/engineering/infrastructure"> Infrastructure </a> </p> <div class="list-post__content-container__title"> <a class="list-post__link t-20 t-black" href="https://www.linkedin.com/blog/engineering/infrastructure/how-design-patterns-power-linkedin-infrastructure"> Navigating the scale: how design patterns power LinkedIn’s inf... </a> </div> <div class="list-post__content-container__byline"> <p class="list-post__content-container__author t-14 t-bold t-black"> Saira Khanum </p> <p class="list-post__content-container__date t-14 t-black--light"> Nov 7, 2024 </p> </div> </div> <div class="list-post__image-container"> <figure class="post__image-figure"> <img class="post__image" data-delayed-url="https://media.licdn.com/dms/image/v2/D4D08AQFO8uu2pzpLYw/croft-frontend-shrinkToFit1024/croft-frontend-shrinkToFit1024/0/1730916560454?e=2147483647&amp;v=beta&amp;t=vB1DIScCG7zlkV699XZ_WzrBab9jRx946etrr-0haC4" data-ghost-url="https://static.licdn.com/aero-v1/sc/h/8pouyb1ly746xtru0x7p2axm0" sizes="(max-width: 480px) 480px, (max-width: 767px) 767px, (max-width: 1024px) 1024px, 480px"> </figure> </div> </li> <li class="post-list__item list-post"> <div class="list-post__content-container"> <p class="list-post__content-container__topic"> <a class="t-14 t-bold" href="https://www.linkedin.com/blog/engineering/infrastructure"> Infrastructure </a> </p> <div class="list-post__content-container__title"> <a class="list-post__link t-20 t-black" href="https://www.linkedin.com/blog/engineering/infrastructure/right-sizing-spark-executor-memory"> Right-sizing Spark executor memory </a> </div> <div class="list-post__content-container__byline"> <p class="list-post__content-container__author t-14 t-bold t-black"> Rob Reeves </p> <!----> <p class="list-post__content-container__date t-14 t-black--light"> Nov 6, 2024 </p> </div> </div> <div class="list-post__image-container"> <figure class="post__image-figure"> <img class="post__image" data-delayed-url="https://media.licdn.com/dms/image/v2/D4D08AQEFejmuyI2nKw/croft-frontend-shrinkToFit1024/croft-frontend-shrinkToFit1024/0/1730841626739?e=2147483647&amp;v=beta&amp;t=5FWzak9rSQPoE9ZpRpQcGzbVMaW2Ll2jvQE9Ob8NJYM" data-ghost-url="https://static.licdn.com/aero-v1/sc/h/8pouyb1ly746xtru0x7p2axm0" sizes="(max-width: 480px) 480px, (max-width: 767px) 767px, (max-width: 1024px) 1024px, 480px"> </figure> </div> </li> </ul> <!----> </section> </div> <!----> </section> </div> <script src="https://static.licdn.com/aero-v1/sc/h/8hfbuq1ftcvnnx4dd5067pi0t" async></script> <script src="https://static.licdn.com/aero-v1/sc/h/dev5px9xu71l67oqmrrbimi6b" async></script> <script src="https://static.licdn.com/aero-v1/sc/h/3e9epkft4bs8unu9ky8gss8ya" async></script> </main> <footer class="li-footer bg-transparent w-full "> <ul class="li-footer__list flex flex-wrap flex-row items-start justify-start w-full h-auto min-h-[50px] my-[0px] mx-auto py-3 px-2 papabear:w-[1128px] papabear:p-0"> <li class="li-footer__item font-sans text-xs text-color-text-low-emphasis flex flex-shrink-0 justify-start p-1 relative w-50% papabear:justify-center papabear:w-auto"> <span class="sr-only">LinkedIn</span> <icon class="li-footer__copy-logo text-color-logo-brand-alt inline-block self-center h-[14px] w-[56px] mr-1" data-delayed-url="https://static.licdn.com/aero-v1/sc/h/e12h2cd8ac580qen9qdd0qks8"></icon> <span class="li-footer__copy-text flex items-center">&copy; 2024</span> </li> <li class="li-footer__item font-sans text-xs text-color-text-low-emphasis flex flex-shrink-0 justify-start p-1 relative w-50% papabear:justify-center papabear:w-auto"> <a class="li-footer__item-link flex items-center font-sans text-xs font-bold text-color-text-low-emphasis hover:text-color-link-hover focus:text-color-link-focus" href="https://about.linkedin.com?trk=content_footer-about" data-tracking-control-name="content_footer-about" data-tracking-will-navigate> About </a> </li> <li class="li-footer__item font-sans text-xs text-color-text-low-emphasis flex flex-shrink-0 justify-start p-1 relative w-50% papabear:justify-center papabear:w-auto"> <a class="li-footer__item-link flex items-center font-sans text-xs font-bold text-color-text-low-emphasis hover:text-color-link-hover focus:text-color-link-focus" href="https://www.linkedin.com/accessibility?trk=content_footer-accessibility" data-tracking-control-name="content_footer-accessibility" data-tracking-will-navigate> Accessibility </a> </li> <li class="li-footer__item font-sans text-xs text-color-text-low-emphasis flex flex-shrink-0 justify-start p-1 relative w-50% papabear:justify-center papabear:w-auto"> <a class="li-footer__item-link flex items-center font-sans text-xs font-bold text-color-text-low-emphasis hover:text-color-link-hover focus:text-color-link-focus" href="https://www.linkedin.com/legal/user-agreement?trk=content_footer-user-agreement" data-tracking-control-name="content_footer-user-agreement" data-tracking-will-navigate> User Agreement </a> </li> <li class="li-footer__item font-sans text-xs text-color-text-low-emphasis flex flex-shrink-0 justify-start p-1 relative w-50% papabear:justify-center papabear:w-auto"> <a class="li-footer__item-link flex items-center font-sans text-xs font-bold text-color-text-low-emphasis hover:text-color-link-hover focus:text-color-link-focus" href="https://www.linkedin.com/legal/privacy-policy?trk=content_footer-privacy-policy" data-tracking-control-name="content_footer-privacy-policy" data-tracking-will-navigate> Privacy Policy </a> </li> <!----> <li class="li-footer__item font-sans text-xs text-color-text-low-emphasis flex flex-shrink-0 justify-start p-1 relative w-50% papabear:justify-center papabear:w-auto"> <a class="li-footer__item-link flex items-center font-sans text-xs font-bold text-color-text-low-emphasis hover:text-color-link-hover focus:text-color-link-focus" href="https://www.linkedin.com/legal/cookie-policy?trk=content_footer-cookie-policy" data-tracking-control-name="content_footer-cookie-policy" data-tracking-will-navigate> Cookie Policy </a> </li> <li class="li-footer__item font-sans text-xs text-color-text-low-emphasis flex flex-shrink-0 justify-start p-1 relative w-50% papabear:justify-center papabear:w-auto"> <a class="li-footer__item-link flex items-center font-sans text-xs font-bold text-color-text-low-emphasis hover:text-color-link-hover focus:text-color-link-focus" href="https://www.linkedin.com/legal/copyright-policy?trk=content_footer-copyright-policy" data-tracking-control-name="content_footer-copyright-policy" data-tracking-will-navigate> Copyright Policy </a> </li> <li class="li-footer__item font-sans text-xs text-color-text-low-emphasis flex flex-shrink-0 justify-start p-1 relative w-50% papabear:justify-center papabear:w-auto"> <a class="li-footer__item-link flex items-center font-sans text-xs font-bold text-color-text-low-emphasis hover:text-color-link-hover focus:text-color-link-focus" href="https://brand.linkedin.com/policies?trk=content_footer-brand-policy" data-tracking-control-name="content_footer-brand-policy" data-tracking-will-navigate> Brand Policy </a> </li> <li class="li-footer__item font-sans text-xs text-color-text-low-emphasis flex flex-shrink-0 justify-start p-1 relative w-50% papabear:justify-center papabear:w-auto"> <a class="li-footer__item-link flex items-center font-sans text-xs font-bold text-color-text-low-emphasis hover:text-color-link-hover focus:text-color-link-focus" href="https://www.linkedin.com/psettings/guest-controls?trk=content_footer-guest-controls" data-tracking-control-name="content_footer-guest-controls" data-tracking-will-navigate> Guest Controls </a> </li> <li class="li-footer__item font-sans text-xs text-color-text-low-emphasis flex flex-shrink-0 justify-start p-1 relative w-50% papabear:justify-center papabear:w-auto"> <a class="li-footer__item-link flex items-center font-sans text-xs font-bold text-color-text-low-emphasis hover:text-color-link-hover focus:text-color-link-focus" href="https://www.linkedin.com/help/linkedin/answer/34593?trk=content_footer-community-guide" data-tracking-control-name="content_footer-community-guide" data-tracking-will-navigate> Community Guidelines </a> </li> <!----> <li class="li-footer__item font-sans text-xs text-color-text-low-emphasis flex flex-shrink-0 justify-start p-1 relative w-50% papabear:justify-center papabear:w-auto"> <div class="collapsible-dropdown collapsible-dropdown--footer collapsible-dropdown--up flex items-center relative hyphens-auto language-selector z-2"> <!----> <ul class="collapsible-dropdown__list hidden container-raised absolute w-auto overflow-y-auto flex-col items-stretch z-1 bottom-[100%] top-auto" role="menu" tabindex="-1"> <li class="language-selector__item" role="presentation"> <!-- Adding aria-label to both the li and the button because screen reader focus goes to button on desktop and li on mobile--> <button aria-label="العربية (Arabic)" class="font-sans text-xs link block py-[5px] px-2 w-full hover:cursor-pointer hover:bg-color-action hover:text-color-text-on-dark focus:bg-color-action focus:text-color-text-on-dark language-selector__link !font-regular" data-tracking-control-name="language-selector-ar_AE" data-locale="ar_AE" role="menuitem" lang="ar_AE"> العربية (Arabic) </button> </li> <li class="language-selector__item" role="presentation"> <!-- Adding aria-label to both the li and the button because screen reader focus goes to button on desktop and li on mobile--> <button aria-label="বাংলা (Bangla)" class="font-sans text-xs link block py-[5px] px-2 w-full hover:cursor-pointer hover:bg-color-action hover:text-color-text-on-dark focus:bg-color-action focus:text-color-text-on-dark language-selector__link !font-regular" data-tracking-control-name="language-selector-bn_IN" data-locale="bn_IN" role="menuitem" lang="bn_IN"> বাংলা (Bangla) </button> </li> <li class="language-selector__item" role="presentation"> <!-- Adding aria-label to both the li and the button because screen reader focus goes to button on desktop and li on mobile--> <button aria-label="Čeština (Czech)" class="font-sans text-xs link block py-[5px] px-2 w-full hover:cursor-pointer hover:bg-color-action hover:text-color-text-on-dark focus:bg-color-action focus:text-color-text-on-dark language-selector__link !font-regular" data-tracking-control-name="language-selector-cs_CZ" data-locale="cs_CZ" role="menuitem" lang="cs_CZ"> Čeština (Czech) </button> </li> <li class="language-selector__item" role="presentation"> <!-- Adding aria-label to both the li and the button because screen reader focus goes to button on desktop and li on mobile--> <button aria-label="Dansk (Danish)" class="font-sans text-xs link block py-[5px] px-2 w-full hover:cursor-pointer hover:bg-color-action hover:text-color-text-on-dark focus:bg-color-action focus:text-color-text-on-dark language-selector__link !font-regular" data-tracking-control-name="language-selector-da_DK" data-locale="da_DK" role="menuitem" lang="da_DK"> Dansk (Danish) </button> </li> <li class="language-selector__item" role="presentation"> <!-- Adding aria-label to both the li and the button because screen reader focus goes to button on desktop and li on mobile--> <button aria-label="Deutsch (German)" class="font-sans text-xs link block py-[5px] px-2 w-full hover:cursor-pointer hover:bg-color-action hover:text-color-text-on-dark focus:bg-color-action focus:text-color-text-on-dark language-selector__link !font-regular" data-tracking-control-name="language-selector-de_DE" data-locale="de_DE" role="menuitem" lang="de_DE"> Deutsch (German) </button> </li> <li class="language-selector__item" role="presentation"> <!-- Adding aria-label to both the li and the button because screen reader focus goes to button on desktop and li on mobile--> <button aria-label="Ελληνικά (Greek)" class="font-sans text-xs link block py-[5px] px-2 w-full hover:cursor-pointer hover:bg-color-action hover:text-color-text-on-dark focus:bg-color-action focus:text-color-text-on-dark language-selector__link !font-regular" data-tracking-control-name="language-selector-el_GR" data-locale="el_GR" role="menuitem" lang="el_GR"> Ελληνικά (Greek) </button> </li> <li class="language-selector__item" role="presentation"> <!-- Adding aria-label to both the li and the button because screen reader focus goes to button on desktop and li on mobile--> <button aria-label="English (English) selected" class="font-sans text-xs link block py-[5px] px-2 w-full hover:cursor-pointer hover:bg-color-action hover:text-color-text-on-dark focus:bg-color-action focus:text-color-text-on-dark language-selector__link--selected" data-tracking-control-name="language-selector-en_US" data-locale="en_US" role="menuitem" lang="en_US"> <strong>English (English)</strong> </button> </li> <li class="language-selector__item" role="presentation"> <!-- Adding aria-label to both the li and the button because screen reader focus goes to button on desktop and li on mobile--> <button aria-label="Español (Spanish)" class="font-sans text-xs link block py-[5px] px-2 w-full hover:cursor-pointer hover:bg-color-action hover:text-color-text-on-dark focus:bg-color-action focus:text-color-text-on-dark language-selector__link !font-regular" data-tracking-control-name="language-selector-es_ES" data-locale="es_ES" role="menuitem" lang="es_ES"> Español (Spanish) </button> </li> <li class="language-selector__item" role="presentation"> <!-- Adding aria-label to both the li and the button because screen reader focus goes to button on desktop and li on mobile--> <button aria-label="فارسی (Persian)" class="font-sans text-xs link block py-[5px] px-2 w-full hover:cursor-pointer hover:bg-color-action hover:text-color-text-on-dark focus:bg-color-action focus:text-color-text-on-dark language-selector__link !font-regular" data-tracking-control-name="language-selector-fa_IR" data-locale="fa_IR" role="menuitem" lang="fa_IR"> فارسی (Persian) </button> </li> <li class="language-selector__item" role="presentation"> <!-- Adding aria-label to both the li and the button because screen reader focus goes to button on desktop and li on mobile--> <button aria-label="Suomi (Finnish)" class="font-sans text-xs link block py-[5px] px-2 w-full hover:cursor-pointer hover:bg-color-action hover:text-color-text-on-dark focus:bg-color-action focus:text-color-text-on-dark language-selector__link !font-regular" data-tracking-control-name="language-selector-fi_FI" data-locale="fi_FI" role="menuitem" lang="fi_FI"> Suomi (Finnish) </button> </li> <li class="language-selector__item" role="presentation"> <!-- Adding aria-label to both the li and the button because screen reader focus goes to button on desktop and li on mobile--> <button aria-label="Français (French)" class="font-sans text-xs link block py-[5px] px-2 w-full hover:cursor-pointer hover:bg-color-action hover:text-color-text-on-dark focus:bg-color-action focus:text-color-text-on-dark language-selector__link !font-regular" data-tracking-control-name="language-selector-fr_FR" data-locale="fr_FR" role="menuitem" lang="fr_FR"> Français (French) </button> </li> <li class="language-selector__item" role="presentation"> <!-- Adding aria-label to both the li and the button because screen reader focus goes to button on desktop and li on mobile--> <button aria-label="हिंदी (Hindi)" class="font-sans text-xs link block py-[5px] px-2 w-full hover:cursor-pointer hover:bg-color-action hover:text-color-text-on-dark focus:bg-color-action focus:text-color-text-on-dark language-selector__link !font-regular" data-tracking-control-name="language-selector-hi_IN" data-locale="hi_IN" role="menuitem" lang="hi_IN"> हिंदी (Hindi) </button> </li> <li class="language-selector__item" role="presentation"> <!-- Adding aria-label to both the li and the button because screen reader focus goes to button on desktop and li on mobile--> <button aria-label="Magyar (Hungarian)" class="font-sans text-xs link block py-[5px] px-2 w-full hover:cursor-pointer hover:bg-color-action hover:text-color-text-on-dark focus:bg-color-action focus:text-color-text-on-dark language-selector__link !font-regular" data-tracking-control-name="language-selector-hu_HU" data-locale="hu_HU" role="menuitem" lang="hu_HU"> Magyar (Hungarian) </button> </li> <li class="language-selector__item" role="presentation"> <!-- Adding aria-label to both the li and the button because screen reader focus goes to button on desktop and li on mobile--> <button aria-label="Bahasa Indonesia (Indonesian)" class="font-sans text-xs link block py-[5px] px-2 w-full hover:cursor-pointer hover:bg-color-action hover:text-color-text-on-dark focus:bg-color-action focus:text-color-text-on-dark language-selector__link !font-regular" data-tracking-control-name="language-selector-in_ID" data-locale="in_ID" role="menuitem" lang="in_ID"> Bahasa Indonesia (Indonesian) </button> </li> <li class="language-selector__item" role="presentation"> <!-- Adding aria-label to both the li and the button because screen reader focus goes to button on desktop and li on mobile--> <button aria-label="Italiano (Italian)" class="font-sans text-xs link block py-[5px] px-2 w-full hover:cursor-pointer hover:bg-color-action hover:text-color-text-on-dark focus:bg-color-action focus:text-color-text-on-dark language-selector__link !font-regular" data-tracking-control-name="language-selector-it_IT" data-locale="it_IT" role="menuitem" lang="it_IT"> Italiano (Italian) </button> </li> <li class="language-selector__item" role="presentation"> <!-- Adding aria-label to both the li and the button because screen reader focus goes to button on desktop and li on mobile--> <button aria-label="עברית (Hebrew)" class="font-sans text-xs link block py-[5px] px-2 w-full hover:cursor-pointer hover:bg-color-action hover:text-color-text-on-dark focus:bg-color-action focus:text-color-text-on-dark language-selector__link !font-regular" data-tracking-control-name="language-selector-iw_IL" data-locale="iw_IL" role="menuitem" lang="iw_IL"> עברית (Hebrew) </button> </li> <li class="language-selector__item" role="presentation"> <!-- Adding aria-label to both the li and the button because screen reader focus goes to button on desktop and li on mobile--> <button aria-label="日本語 (Japanese)" class="font-sans text-xs link block py-[5px] px-2 w-full hover:cursor-pointer hover:bg-color-action hover:text-color-text-on-dark focus:bg-color-action focus:text-color-text-on-dark language-selector__link !font-regular" data-tracking-control-name="language-selector-ja_JP" data-locale="ja_JP" role="menuitem" lang="ja_JP"> 日本語 (Japanese) </button> </li> <li class="language-selector__item" role="presentation"> <!-- Adding aria-label to both the li and the button because screen reader focus goes to button on desktop and li on mobile--> <button aria-label="한국어 (Korean)" class="font-sans text-xs link block py-[5px] px-2 w-full hover:cursor-pointer hover:bg-color-action hover:text-color-text-on-dark focus:bg-color-action focus:text-color-text-on-dark language-selector__link !font-regular" data-tracking-control-name="language-selector-ko_KR" data-locale="ko_KR" role="menuitem" lang="ko_KR"> 한국어 (Korean) </button> </li> <li class="language-selector__item" role="presentation"> <!-- Adding aria-label to both the li and the button because screen reader focus goes to button on desktop and li on mobile--> <button aria-label="मराठी (Marathi)" class="font-sans text-xs link block py-[5px] px-2 w-full hover:cursor-pointer hover:bg-color-action hover:text-color-text-on-dark focus:bg-color-action focus:text-color-text-on-dark language-selector__link !font-regular" data-tracking-control-name="language-selector-mr_IN" data-locale="mr_IN" role="menuitem" lang="mr_IN"> मराठी (Marathi) </button> </li> <li class="language-selector__item" role="presentation"> <!-- Adding aria-label to both the li and the button because screen reader focus goes to button on desktop and li on mobile--> <button aria-label="Bahasa Malaysia (Malay)" class="font-sans text-xs link block py-[5px] px-2 w-full hover:cursor-pointer hover:bg-color-action hover:text-color-text-on-dark focus:bg-color-action focus:text-color-text-on-dark language-selector__link !font-regular" data-tracking-control-name="language-selector-ms_MY" data-locale="ms_MY" role="menuitem" lang="ms_MY"> Bahasa Malaysia (Malay) </button> </li> <li class="language-selector__item" role="presentation"> <!-- Adding aria-label to both the li and the button because screen reader focus goes to button on desktop and li on mobile--> <button aria-label="Nederlands (Dutch)" class="font-sans text-xs link block py-[5px] px-2 w-full hover:cursor-pointer hover:bg-color-action hover:text-color-text-on-dark focus:bg-color-action focus:text-color-text-on-dark language-selector__link !font-regular" data-tracking-control-name="language-selector-nl_NL" data-locale="nl_NL" role="menuitem" lang="nl_NL"> Nederlands (Dutch) </button> </li> <li class="language-selector__item" role="presentation"> <!-- Adding aria-label to both the li and the button because screen reader focus goes to button on desktop and li on mobile--> <button aria-label="Norsk (Norwegian)" class="font-sans text-xs link block py-[5px] px-2 w-full hover:cursor-pointer hover:bg-color-action hover:text-color-text-on-dark focus:bg-color-action focus:text-color-text-on-dark language-selector__link !font-regular" data-tracking-control-name="language-selector-no_NO" data-locale="no_NO" role="menuitem" lang="no_NO"> Norsk (Norwegian) </button> </li> <li class="language-selector__item" role="presentation"> <!-- Adding aria-label to both the li and the button because screen reader focus goes to button on desktop and li on mobile--> <button aria-label="ਪੰਜਾਬੀ (Punjabi)" class="font-sans text-xs link block py-[5px] px-2 w-full hover:cursor-pointer hover:bg-color-action hover:text-color-text-on-dark focus:bg-color-action focus:text-color-text-on-dark language-selector__link !font-regular" data-tracking-control-name="language-selector-pa_IN" data-locale="pa_IN" role="menuitem" lang="pa_IN"> ਪੰਜਾਬੀ (Punjabi) </button> </li> <li class="language-selector__item" role="presentation"> <!-- Adding aria-label to both the li and the button because screen reader focus goes to button on desktop and li on mobile--> <button aria-label="Polski (Polish)" class="font-sans text-xs link block py-[5px] px-2 w-full hover:cursor-pointer hover:bg-color-action hover:text-color-text-on-dark focus:bg-color-action focus:text-color-text-on-dark language-selector__link !font-regular" data-tracking-control-name="language-selector-pl_PL" data-locale="pl_PL" role="menuitem" lang="pl_PL"> Polski (Polish) </button> </li> <li class="language-selector__item" role="presentation"> <!-- Adding aria-label to both the li and the button because screen reader focus goes to button on desktop and li on mobile--> <button aria-label="Português (Portuguese)" class="font-sans text-xs link block py-[5px] px-2 w-full hover:cursor-pointer hover:bg-color-action hover:text-color-text-on-dark focus:bg-color-action focus:text-color-text-on-dark language-selector__link !font-regular" data-tracking-control-name="language-selector-pt_BR" data-locale="pt_BR" role="menuitem" lang="pt_BR"> Português (Portuguese) </button> </li> <li class="language-selector__item" role="presentation"> <!-- Adding aria-label to both the li and the button because screen reader focus goes to button on desktop and li on mobile--> <button aria-label="Română (Romanian)" class="font-sans text-xs link block py-[5px] px-2 w-full hover:cursor-pointer hover:bg-color-action hover:text-color-text-on-dark focus:bg-color-action focus:text-color-text-on-dark language-selector__link !font-regular" data-tracking-control-name="language-selector-ro_RO" data-locale="ro_RO" role="menuitem" lang="ro_RO"> Română (Romanian) </button> </li> <li class="language-selector__item" role="presentation"> <!-- Adding aria-label to both the li and the button because screen reader focus goes to button on desktop and li on mobile--> <button aria-label="Русский (Russian)" class="font-sans text-xs link block py-[5px] px-2 w-full hover:cursor-pointer hover:bg-color-action hover:text-color-text-on-dark focus:bg-color-action focus:text-color-text-on-dark language-selector__link !font-regular" data-tracking-control-name="language-selector-ru_RU" data-locale="ru_RU" role="menuitem" lang="ru_RU"> Русский (Russian) </button> </li> <li class="language-selector__item" role="presentation"> <!-- Adding aria-label to both the li and the button because screen reader focus goes to button on desktop and li on mobile--> <button aria-label="Svenska (Swedish)" class="font-sans text-xs link block py-[5px] px-2 w-full hover:cursor-pointer hover:bg-color-action hover:text-color-text-on-dark focus:bg-color-action focus:text-color-text-on-dark language-selector__link !font-regular" data-tracking-control-name="language-selector-sv_SE" data-locale="sv_SE" role="menuitem" lang="sv_SE"> Svenska (Swedish) </button> </li> <li class="language-selector__item" role="presentation"> <!-- Adding aria-label to both the li and the button because screen reader focus goes to button on desktop and li on mobile--> <button aria-label="తెలుగు (Telugu)" class="font-sans text-xs link block py-[5px] px-2 w-full hover:cursor-pointer hover:bg-color-action hover:text-color-text-on-dark focus:bg-color-action focus:text-color-text-on-dark language-selector__link !font-regular" data-tracking-control-name="language-selector-te_IN" data-locale="te_IN" role="menuitem" lang="te_IN"> తెలుగు (Telugu) </button> </li> <li class="language-selector__item" role="presentation"> <!-- Adding aria-label to both the li and the button because screen reader focus goes to button on desktop and li on mobile--> <button aria-label="ภาษาไทย (Thai)" class="font-sans text-xs link block py-[5px] px-2 w-full hover:cursor-pointer hover:bg-color-action hover:text-color-text-on-dark focus:bg-color-action focus:text-color-text-on-dark language-selector__link !font-regular" data-tracking-control-name="language-selector-th_TH" data-locale="th_TH" role="menuitem" lang="th_TH"> ภาษาไทย (Thai) </button> </li> <li class="language-selector__item" role="presentation"> <!-- Adding aria-label to both the li and the button because screen reader focus goes to button on desktop and li on mobile--> <button aria-label="Tagalog (Tagalog)" class="font-sans text-xs link block py-[5px] px-2 w-full hover:cursor-pointer hover:bg-color-action hover:text-color-text-on-dark focus:bg-color-action focus:text-color-text-on-dark language-selector__link !font-regular" data-tracking-control-name="language-selector-tl_PH" data-locale="tl_PH" role="menuitem" lang="tl_PH"> Tagalog (Tagalog) </button> </li> <li class="language-selector__item" role="presentation"> <!-- Adding aria-label to both the li and the button because screen reader focus goes to button on desktop and li on mobile--> <button aria-label="Türkçe (Turkish)" class="font-sans text-xs link block py-[5px] px-2 w-full hover:cursor-pointer hover:bg-color-action hover:text-color-text-on-dark focus:bg-color-action focus:text-color-text-on-dark language-selector__link !font-regular" data-tracking-control-name="language-selector-tr_TR" data-locale="tr_TR" role="menuitem" lang="tr_TR"> Türkçe (Turkish) </button> </li> <li class="language-selector__item" role="presentation"> <!-- Adding aria-label to both the li and the button because screen reader focus goes to button on desktop and li on mobile--> <button aria-label="Українська (Ukrainian)" class="font-sans text-xs link block py-[5px] px-2 w-full hover:cursor-pointer hover:bg-color-action hover:text-color-text-on-dark focus:bg-color-action focus:text-color-text-on-dark language-selector__link !font-regular" data-tracking-control-name="language-selector-uk_UA" data-locale="uk_UA" role="menuitem" lang="uk_UA"> Українська (Ukrainian) </button> </li> <li class="language-selector__item" role="presentation"> <!-- Adding aria-label to both the li and the button because screen reader focus goes to button on desktop and li on mobile--> <button aria-label="Tiếng Việt (Vietnamese)" class="font-sans text-xs link block py-[5px] px-2 w-full hover:cursor-pointer hover:bg-color-action hover:text-color-text-on-dark focus:bg-color-action focus:text-color-text-on-dark language-selector__link !font-regular" data-tracking-control-name="language-selector-vi_VN" data-locale="vi_VN" role="menuitem" lang="vi_VN"> Tiếng Việt (Vietnamese) </button> </li> <li class="language-selector__item" role="presentation"> <!-- Adding aria-label to both the li and the button because screen reader focus goes to button on desktop and li on mobile--> <button aria-label="简体中文 (Chinese (Simplified))" class="font-sans text-xs link block py-[5px] px-2 w-full hover:cursor-pointer hover:bg-color-action hover:text-color-text-on-dark focus:bg-color-action focus:text-color-text-on-dark language-selector__link !font-regular" data-tracking-control-name="language-selector-zh_CN" data-locale="zh_CN" role="menuitem" lang="zh_CN"> 简体中文 (Chinese (Simplified)) </button> </li> <li class="language-selector__item" role="presentation"> <!-- Adding aria-label to both the li and the button because screen reader focus goes to button on desktop and li on mobile--> <button aria-label="正體中文 (Chinese (Traditional))" class="font-sans text-xs link block py-[5px] px-2 w-full hover:cursor-pointer hover:bg-color-action hover:text-color-text-on-dark focus:bg-color-action focus:text-color-text-on-dark language-selector__link !font-regular" data-tracking-control-name="language-selector-zh_TW" data-locale="zh_TW" role="menuitem" lang="zh_TW"> 正體中文 (Chinese (Traditional)) </button> </li> <!----> </ul> <button class="language-selector__button select-none relative pr-2 font-sans text-xs font-bold text-color-text-low-emphasis hover:text-color-link-hover hover:cursor-pointer focus:text-color-link-focus focus:outline-dotted focus:outline-1" aria-expanded="false" data-tracking-control-name="footer-lang-dropdown_trigger"> <span class="language-selector__label-text mr-0.5 break-words"> Language </span> <icon class="language-selector__label-chevron w-2 h-2 absolute top-0 right-0" data-delayed-url="https://static.licdn.com/aero-v1/sc/h/cyolgscd0imw2ldqppkrb84vo"></icon> </button> </div> </li> </ul> <!----> </footer> <script src="https://static.licdn.com/aero-v1/sc/h/eh08muqvrde4h3hc6koyij5ti" async></script> <!----> </body> </html>

Pages: 1 2 3 4 5 6 7 8 9 10