├── .config ├── .cprc.json ├── .eslintrc ├── .prettierrc.js ├── Dockerfile ├── README.md ├── entrypoint.sh ├── jest-setup.js ├── jest.config.js ├── jest │ ├── mocks │ │ └── react-inlinesvg.tsx │ └── utils.js ├── supervisord │ └── supervisord.conf ├── tsconfig.json ├── types │ └── custom.d.ts └── webpack │ ├── constants.ts │ ├── publicPath.ts │ ├── utils.ts │ └── webpack.config.ts ├── .cprc.json ├── .eslintrc ├── .gitignore ├── .nvmrc ├── .prettierrc.js ├── .vscode └── settings.json ├── .yarnrc.yml ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── LICENSE.txt ├── Magefile.go ├── README.md ├── SECURITY.md ├── THIRD_PARTY_LICENSES.txt ├── build.sh ├── build_spec.yaml ├── docs ├── compatmatrix.md ├── datasource_configuration.md ├── grafanacloud.md ├── images │ ├── Grafana-AddDataSource-Screenshot.png │ ├── Grafana-ChangeDefaultAdminPassword-Screenshot.png │ ├── Grafana-ConfigurationPluginsMenu-Screenshot.png │ ├── Grafana-ConfigurationPluginsSearch-Screenshot.png │ ├── Grafana-ConfigurationPluginsWindow-Screenshot.png │ ├── Grafana-CreateDashboardMenu-Screenshot.png │ ├── Grafana-CreateDashboardWindow-Screenshot.png │ ├── Grafana-DataSourceSearch-Screenshot.png │ ├── Grafana-NewPanelEditor-Apply-Screenshot.png │ ├── Grafana-NewPanelEditor-DataSource-Screenshot.png │ ├── Grafana-NewPanelEditor-PanelTitle-Screenshot.png │ ├── Grafana-NewPanelEditor-PanelType-Screenshot.png │ ├── Grafana-NewPanelEditor-QueryBox-Screenshot.png │ ├── Grafana-NewPanelEditor-Region-Screenshot.png │ ├── Grafana-NewPanelEditor-TablePanelType-Screenshot.png │ ├── Grafana-OCILogsPluginConfigWindow-Screenshot.png │ ├── Grafana-OCILogsPluginInstallWindow-Screenshot.png │ ├── Grafana-OCILogsPluginInstalled-Screenshot.png │ ├── Grafana-SelectOCILogsDataSource-Screenshot.png │ ├── Grafana-TablePanel-EndResult-Screenshot.png │ ├── Grafana-TablePanel-ExtractFieldsFormat-Screenshot.png │ ├── Grafana-TablePanel-ExtractFieldsResult-Screenshot.png │ ├── Grafana-TablePanel-ExtractFieldsSource-Screenshot.png │ ├── Grafana-TablePanel-Screenshot.png │ ├── Grafana-TablePanel-Xform-Screenshot.png │ ├── Grafana-TablePanel-XformSelection-Screenshot.png │ ├── Grafana-TemplateVars-BackToVarsScreen-Screenshot.png │ ├── Grafana-TemplateVars-DashboardSettingsIcon-Screenshot.png │ ├── Grafana-TemplateVars-DashboardSettingsScreen-Screenshot.png │ ├── Grafana-TemplateVars-ExampleDropdown-Screenshot.png │ ├── Grafana-TemplateVars-IntervalVarConfig-Screenshot.png │ ├── Grafana-TemplateVars-OfficialVars-Screenshot.png │ ├── Grafana-TemplateVars-PanelEditor-Screenshot.png │ ├── Grafana-TemplateVars-PanelEditorWithVars-Screenshot.png │ ├── Grafana-TemplateVars-Regions-Screenshot.png │ ├── Grafana-TemplateVars-SelectionOptions-Screenshot.png │ ├── Grafana-TemplateVars-VariablesScreen-NewVar-Screenshot.png │ ├── Grafana-TemplateVars-VariablesScreen-Screenshot.png │ ├── Grafana-TimeSeries-AliasesExample1-Screenshot.png │ ├── Grafana-TimeSeries-CustomQueryOptionsExample-Screenshot.png │ ├── Grafana-TimeSeries-ExampleGraph-Screenshot.png │ ├── Grafana-TimeSeries-GroupByExample1-Screenshot.png │ ├── Grafana-TimeSeries-GroupByExample2-Screenshot.png │ ├── Grafana-TimeSeries-PanelOptions-Screenshot.png │ ├── Grafana-TimeSeries-PluginIntervalExample-Screenshot.png │ ├── Grafana-TimeSeries-QueryOptions-Screenshot.png │ ├── Grafana-TimeSeries-rounddownExample-Screenshot.png │ ├── GrafanaHomePage-Screenshot.png │ ├── GrafanaLogin-Screenshot.png │ ├── OCIConsole-DynamicGroupList-Screenshot.png │ ├── OCIConsole-GroupList-Screenshot.png │ ├── OCIConsole-GroupLogsPolicyCreate-Screenshot.png │ ├── OCIConsole-PoliciesList-Screenshot.png │ ├── Screen Shot 2018-12-17 at 3.58.23 PM.png │ ├── Screen Shot 2018-12-17 at 3.59.38 PM.png │ ├── Screen Shot 2018-12-17 at 4.01.34 PM.png │ ├── Screen Shot 2018-12-17 at 4.01.47 PM.png │ ├── Screen Shot 2018-12-17 at 4.04.42 PM.png │ ├── create-alert-expression.png │ ├── custom_var.png │ ├── datasource_single_empty.png │ ├── datasource_single_full.png │ ├── dgGroup.png │ ├── dgPolicy.png │ ├── grafanacloud-adddatasource.png │ ├── grafanacloud-administration.png │ ├── grafanacloud-installlogs.png │ ├── grafanacloud-login.png │ ├── grafanacloud-oneclick.png │ ├── grafanacloud-plugins.png │ ├── grafanacloud-searchdatasource.png │ ├── instance_principals.png │ ├── log_var_custom.png │ ├── logs_multi_filled.png │ ├── logs_single_filled.png │ ├── multi_disable.png │ ├── multi_regions.png │ ├── multi_templating_tenancies.png │ ├── multi_templating_vars.png │ ├── multi_tenancy.png │ ├── oci_administration.png │ ├── oci_apikey.png │ ├── oci_fingerprint.png │ ├── oci_tenancy.png │ ├── oci_user.png │ ├── usrGp.png │ └── usrPolicy.png ├── kubernetes.md ├── linux.md ├── linuxoci.md ├── macos.md ├── migration.md ├── terraform.md └── using.md ├── generate_region_list.py ├── go.mod ├── go.sum ├── jest-setup.js ├── jest.config.js ├── package.json ├── pkg ├── main.go └── plugin │ ├── constants │ └── constants.go │ ├── logging_functions.go │ ├── models │ ├── datasource_settings.go │ ├── http_error.go │ ├── oci.go │ ├── query.go │ └── request.go │ ├── plugin.go │ ├── query.go │ ├── resource_handler.go │ └── utils.go ├── sbom_generation.yaml ├── src ├── .eslintrc ├── ConfigEditor.tsx ├── QueryEditor.tsx ├── config.options.ts ├── datasource.ts ├── img │ ├── OCI_Logs.png │ └── Oracle-cloud.svg ├── module.ts ├── plugin.json ├── query_model.ts ├── regionlist.ts ├── resource.response.parser.ts └── types.ts ├── tsconfig.json └── yarn.lock /.config/.cprc.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "4.16.1" 3 | } 4 | -------------------------------------------------------------------------------- /.config/.eslintrc: -------------------------------------------------------------------------------- 1 | /* 2 | * ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️ 3 | * 4 | * In order to extend the configuration follow the steps in 5 | * https://grafana.com/developers/plugin-tools/create-a-plugin/extend-a-plugin/extend-configurations#extend-the-eslint-config 6 | */ 7 | { 8 | "extends": ["@grafana/eslint-config"], 9 | "root": true, 10 | "rules": { 11 | "react/prop-types": "off" 12 | }, 13 | "overrides": [ 14 | { 15 | "plugins": ["deprecation"], 16 | "files": ["src/**/*.{ts,tsx}"], 17 | "rules": { 18 | "deprecation/deprecation": "warn" 19 | }, 20 | "parserOptions": { 21 | "project": "./tsconfig.json" 22 | } 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /.config/.prettierrc.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️ 3 | * 4 | * In order to extend the configuration follow the steps in .config/README.md 5 | */ 6 | 7 | module.exports = { 8 | endOfLine: 'auto', 9 | printWidth: 120, 10 | trailingComma: 'es5', 11 | semi: true, 12 | jsxSingleQuote: false, 13 | singleQuote: true, 14 | useTabs: false, 15 | tabWidth: 2, 16 | }; 17 | -------------------------------------------------------------------------------- /.config/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG grafana_version=latest 2 | ARG grafana_image=grafana-enterprise 3 | 4 | FROM grafana/${grafana_image}:${grafana_version} 5 | 6 | ARG development=false 7 | ARG TARGETARCH 8 | 9 | ARG GO_VERSION=1.21.6 10 | ARG GO_ARCH=${TARGETARCH:-amd64} 11 | 12 | ENV DEV "${development}" 13 | 14 | # Make it as simple as possible to access the grafana instance for development purposes 15 | # Do NOT enable these settings in a public facing / production grafana instance 16 | ENV GF_AUTH_ANONYMOUS_ORG_ROLE "Admin" 17 | ENV GF_AUTH_ANONYMOUS_ENABLED "true" 18 | ENV GF_AUTH_BASIC_ENABLED "false" 19 | # Set development mode so plugins can be loaded without the need to sign 20 | ENV GF_DEFAULT_APP_MODE "development" 21 | 22 | 23 | LABEL maintainer="Grafana Labs " 24 | 25 | ENV GF_PATHS_HOME="/usr/share/grafana" 26 | WORKDIR $GF_PATHS_HOME 27 | 28 | USER root 29 | 30 | # Installing supervisor and inotify-tools 31 | RUN if [ "${development}" = "true" ]; then \ 32 | if grep -i -q alpine /etc/issue; then \ 33 | apk add supervisor inotify-tools git; \ 34 | elif grep -i -q ubuntu /etc/issue; then \ 35 | DEBIAN_FRONTEND=noninteractive && \ 36 | apt-get update && \ 37 | apt-get install -y supervisor inotify-tools git && \ 38 | rm -rf /var/lib/apt/lists/*; \ 39 | else \ 40 | echo 'ERROR: Unsupported base image' && /bin/false; \ 41 | fi \ 42 | fi 43 | 44 | COPY supervisord/supervisord.conf /etc/supervisor.d/supervisord.ini 45 | COPY supervisord/supervisord.conf /etc/supervisor/conf.d/supervisord.conf 46 | 47 | 48 | # Installing Go 49 | RUN if [ "${development}" = "true" ]; then \ 50 | curl -O -L https://golang.org/dl/go${GO_VERSION}.linux-${GO_ARCH}.tar.gz && \ 51 | rm -rf /usr/local/go && \ 52 | tar -C /usr/local -xzf go${GO_VERSION}.linux-${GO_ARCH}.tar.gz && \ 53 | echo "export PATH=$PATH:/usr/local/go/bin:~/go/bin" >> ~/.bashrc && \ 54 | rm -f go${GO_VERSION}.linux-${GO_ARCH}.tar.gz; \ 55 | fi 56 | 57 | # Installing delve for debugging 58 | RUN if [ "${development}" = "true" ]; then \ 59 | /usr/local/go/bin/go install github.com/go-delve/delve/cmd/dlv@latest; \ 60 | fi 61 | 62 | # Installing mage for plugin (re)building 63 | RUN if [ "${development}" = "true" ]; then \ 64 | git clone https://github.com/magefile/mage; \ 65 | cd mage; \ 66 | export PATH=$PATH:/usr/local/go/bin; \ 67 | go run bootstrap.go; \ 68 | fi 69 | 70 | # Inject livereload script into grafana index.html 71 | RUN sed -i 's|||g' /usr/share/grafana/public/views/index.html 72 | 73 | 74 | COPY entrypoint.sh /entrypoint.sh 75 | RUN chmod +x /entrypoint.sh 76 | ENTRYPOINT ["/entrypoint.sh"] 77 | -------------------------------------------------------------------------------- /.config/README.md: -------------------------------------------------------------------------------- 1 | # Default build configuration by Grafana 2 | 3 | **This is an auto-generated directory and is not intended to be changed! ⚠️** 4 | 5 | The `.config/` directory holds basic configuration for the different tools 6 | that are used to develop, test and build the project. In order to make it updates easier we ask you to 7 | not edit files in this folder to extend configuration. 8 | 9 | ## How to extend the basic configs? 10 | 11 | Bear in mind that you are doing it at your own risk, and that extending any of the basic configuration can lead 12 | to issues around working with the project. 13 | 14 | ### Extending the ESLint config 15 | 16 | Edit the `.eslintrc` file in the project root in order to extend the ESLint configuration. 17 | 18 | **Example:** 19 | 20 | ```json 21 | { 22 | "extends": "./.config/.eslintrc", 23 | "rules": { 24 | "react/prop-types": "off" 25 | } 26 | } 27 | ``` 28 | 29 | --- 30 | 31 | ### Extending the Prettier config 32 | 33 | Edit the `.prettierrc.js` file in the project root in order to extend the Prettier configuration. 34 | 35 | **Example:** 36 | 37 | ```javascript 38 | module.exports = { 39 | // Prettier configuration provided by Grafana scaffolding 40 | ...require('./.config/.prettierrc.js'), 41 | 42 | semi: false, 43 | }; 44 | ``` 45 | 46 | --- 47 | 48 | ### Extending the Jest config 49 | 50 | There are two configuration in the project root that belong to Jest: `jest-setup.js` and `jest.config.js`. 51 | 52 | **`jest-setup.js`:** A file that is run before each test file in the suite is executed. We are using it to 53 | set up the Jest DOM for the testing library and to apply some polyfills. ([link to Jest docs](https://jestjs.io/docs/configuration#setupfilesafterenv-array)) 54 | 55 | **`jest.config.js`:** The main Jest configuration file that extends the Grafana recommended setup. ([link to Jest docs](https://jestjs.io/docs/configuration)) 56 | 57 | #### ESM errors with Jest 58 | 59 | A common issue with the current jest config involves importing an npm package that only offers an ESM build. These packages cause jest to error with `SyntaxError: Cannot use import statement outside a module`. To work around this, we provide a list of known packages to pass to the `[transformIgnorePatterns](https://jestjs.io/docs/configuration#transformignorepatterns-arraystring)` jest configuration property. If need be, this can be extended in the following way: 60 | 61 | ```javascript 62 | process.env.TZ = 'UTC'; 63 | const { grafanaESModules, nodeModulesToTransform } = require('./config/jest/utils'); 64 | 65 | module.exports = { 66 | // Jest configuration provided by Grafana 67 | ...require('./.config/jest.config'), 68 | // Inform jest to only transform specific node_module packages. 69 | transformIgnorePatterns: [nodeModulesToTransform([...grafanaESModules, 'packageName'])], 70 | }; 71 | ``` 72 | 73 | --- 74 | 75 | ### Extending the TypeScript config 76 | 77 | Edit the `tsconfig.json` file in the project root in order to extend the TypeScript configuration. 78 | 79 | **Example:** 80 | 81 | ```json 82 | { 83 | "extends": "./.config/tsconfig.json", 84 | "compilerOptions": { 85 | "preserveConstEnums": true 86 | } 87 | } 88 | ``` 89 | 90 | --- 91 | 92 | ### Extending the Webpack config 93 | 94 | Follow these steps to extend the basic Webpack configuration that lives under `.config/`: 95 | 96 | #### 1. Create a new Webpack configuration file 97 | 98 | Create a new config file that is going to extend the basic one provided by Grafana. 99 | It can live in the project root, e.g. `webpack.config.ts`. 100 | 101 | #### 2. Merge the basic config provided by Grafana and your custom setup 102 | 103 | We are going to use [`webpack-merge`](https://github.com/survivejs/webpack-merge) for this. 104 | 105 | ```typescript 106 | // webpack.config.ts 107 | import type { Configuration } from 'webpack'; 108 | import { merge } from 'webpack-merge'; 109 | import grafanaConfig from './.config/webpack/webpack.config'; 110 | 111 | const config = async (env): Promise => { 112 | const baseConfig = await grafanaConfig(env); 113 | 114 | return merge(baseConfig, { 115 | // Add custom config here... 116 | output: { 117 | asyncChunks: true, 118 | }, 119 | }); 120 | }; 121 | 122 | export default config; 123 | ``` 124 | 125 | #### 3. Update the `package.json` to use the new Webpack config 126 | 127 | We need to update the `scripts` in the `package.json` to use the extended Webpack configuration. 128 | 129 | **Update for `build`:** 130 | 131 | ```diff 132 | -"build": "webpack -c ./.config/webpack/webpack.config.ts --env production", 133 | +"build": "webpack -c ./webpack.config.ts --env production", 134 | ``` 135 | 136 | **Update for `dev`:** 137 | 138 | ```diff 139 | -"dev": "webpack -w -c ./.config/webpack/webpack.config.ts --env development", 140 | +"dev": "webpack -w -c ./webpack.config.ts --env development", 141 | ``` 142 | 143 | ### Configure grafana image to use when running docker 144 | 145 | By default, `grafana-enterprise` will be used as the docker image for all docker related commands. If you want to override this behavior, simply alter the `docker-compose.yaml` by adding the following build arg `grafana_image`. 146 | 147 | **Example:** 148 | 149 | ```yaml 150 | version: '3.7' 151 | 152 | services: 153 | grafana: 154 | container_name: 'myorg-basic-app' 155 | build: 156 | context: ./.config 157 | args: 158 | grafana_version: ${GRAFANA_VERSION:-9.1.2} 159 | grafana_image: ${GRAFANA_IMAGE:-grafana} 160 | ``` 161 | 162 | In this example, we assign the environment variable `GRAFANA_IMAGE` to the build arg `grafana_image` with a default value of `grafana`. This will allow you to set the value while running the docker-compose commands, which might be convenient in some scenarios. 163 | 164 | --- 165 | -------------------------------------------------------------------------------- /.config/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ "${DEV}" = "false" ]; then 4 | echo "Starting test mode" 5 | exec /run.sh 6 | fi 7 | 8 | echo "Starting development mode" 9 | 10 | if grep -i -q alpine /etc/issue; then 11 | exec /usr/bin/supervisord -c /etc/supervisord.conf 12 | elif grep -i -q ubuntu /etc/issue; then 13 | exec /usr/bin/supervisord -c /etc/supervisor/supervisord.conf 14 | else 15 | echo 'ERROR: Unsupported base image' 16 | exit 1 17 | fi 18 | 19 | -------------------------------------------------------------------------------- /.config/jest-setup.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️ 3 | * 4 | * In order to extend the configuration follow the steps in 5 | * https://grafana.com/developers/plugin-tools/create-a-plugin/extend-a-plugin/extend-configurations#extend-the-jest-config 6 | */ 7 | 8 | import '@testing-library/jest-dom'; 9 | import { TextEncoder, TextDecoder } from 'util'; 10 | 11 | Object.assign(global, { TextDecoder, TextEncoder }); 12 | 13 | // https://jestjs.io/docs/manual-mocks#mocking-methods-which-are-not-implemented-in-jsdom 14 | Object.defineProperty(global, 'matchMedia', { 15 | writable: true, 16 | value: jest.fn().mockImplementation((query) => ({ 17 | matches: false, 18 | media: query, 19 | onchange: null, 20 | addListener: jest.fn(), // deprecated 21 | removeListener: jest.fn(), // deprecated 22 | addEventListener: jest.fn(), 23 | removeEventListener: jest.fn(), 24 | dispatchEvent: jest.fn(), 25 | })), 26 | }); 27 | 28 | HTMLCanvasElement.prototype.getContext = () => {}; 29 | -------------------------------------------------------------------------------- /.config/jest.config.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️ 3 | * 4 | * In order to extend the configuration follow the steps in 5 | * https://grafana.com/developers/plugin-tools/create-a-plugin/extend-a-plugin/extend-configurations#extend-the-jest-config 6 | */ 7 | 8 | const path = require('path'); 9 | const { grafanaESModules, nodeModulesToTransform } = require('./jest/utils'); 10 | 11 | module.exports = { 12 | moduleNameMapper: { 13 | '\\.(css|scss|sass)$': 'identity-obj-proxy', 14 | 'react-inlinesvg': path.resolve(__dirname, 'jest', 'mocks', 'react-inlinesvg.tsx'), 15 | }, 16 | modulePaths: ['/src'], 17 | setupFilesAfterEnv: ['/jest-setup.js'], 18 | testEnvironment: 'jest-environment-jsdom', 19 | testMatch: [ 20 | '/src/**/__tests__/**/*.{js,jsx,ts,tsx}', 21 | '/src/**/*.{spec,test,jest}.{js,jsx,ts,tsx}', 22 | '/src/**/*.{spec,test,jest}.{js,jsx,ts,tsx}', 23 | ], 24 | transform: { 25 | '^.+\\.(t|j)sx?$': [ 26 | '@swc/jest', 27 | { 28 | sourceMaps: 'inline', 29 | jsc: { 30 | parser: { 31 | syntax: 'typescript', 32 | tsx: true, 33 | decorators: false, 34 | dynamicImport: true, 35 | }, 36 | }, 37 | }, 38 | ], 39 | }, 40 | // Jest will throw `Cannot use import statement outside module` if it tries to load an 41 | // ES module without it being transformed first. ./config/README.md#esm-errors-with-jest 42 | transformIgnorePatterns: [nodeModulesToTransform(grafanaESModules)], 43 | }; 44 | -------------------------------------------------------------------------------- /.config/jest/mocks/react-inlinesvg.tsx: -------------------------------------------------------------------------------- 1 | // Due to the grafana/ui Icon component making fetch requests to 2 | // `/public/img/icon/.svg` we need to mock react-inlinesvg to prevent 3 | // the failed fetch requests from displaying errors in console. 4 | 5 | import React from 'react'; 6 | 7 | type Callback = (...args: any[]) => void; 8 | 9 | export interface StorageItem { 10 | content: string; 11 | queue: Callback[]; 12 | status: string; 13 | } 14 | 15 | export const cacheStore: { [key: string]: StorageItem } = Object.create(null); 16 | 17 | const SVG_FILE_NAME_REGEX = /(.+)\/(.+)\.svg$/; 18 | 19 | const InlineSVG = ({ src }: { src: string }) => { 20 | // testId will be the file name without extension (e.g. `public/img/icons/angle-double-down.svg` -> `angle-double-down`) 21 | const testId = src.replace(SVG_FILE_NAME_REGEX, '$2'); 22 | return ; 23 | }; 24 | 25 | export default InlineSVG; 26 | -------------------------------------------------------------------------------- /.config/jest/utils.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️ 3 | * 4 | * In order to extend the configuration follow the steps in .config/README.md 5 | */ 6 | 7 | /* 8 | * This utility function is useful in combination with jest `transformIgnorePatterns` config 9 | * to transform specific packages (e.g.ES modules) in a projects node_modules folder. 10 | */ 11 | const nodeModulesToTransform = (moduleNames) => `node_modules\/(?!.*(${moduleNames.join('|')})\/.*)`; 12 | 13 | // Array of known nested grafana package dependencies that only bundle an ESM version 14 | const grafanaESModules = [ 15 | '.pnpm', // Support using pnpm symlinked packages 16 | '@grafana/schema', 17 | 'd3', 18 | 'd3-color', 19 | 'd3-force', 20 | 'd3-interpolate', 21 | 'd3-scale-chromatic', 22 | 'ol', 23 | 'react-colorful', 24 | 'rxjs', 25 | 'uuid', 26 | ]; 27 | 28 | module.exports = { 29 | nodeModulesToTransform, 30 | grafanaESModules, 31 | }; 32 | -------------------------------------------------------------------------------- /.config/supervisord/supervisord.conf: -------------------------------------------------------------------------------- 1 | [supervisord] 2 | nodaemon=true 3 | user=root 4 | 5 | [program:grafana] 6 | user=root 7 | directory=/var/lib/grafana 8 | command=bash -c 'while [ ! -f /root/oci-logs-datasource/dist/oci-logs-plugin* ]; do sleep 1; done; /run.sh' 9 | stdout_logfile=/dev/fd/1 10 | stdout_logfile_maxbytes=0 11 | redirect_stderr=true 12 | killasgroup=true 13 | stopasgroup=true 14 | autostart=true 15 | 16 | [program:delve] 17 | user=root 18 | command=/bin/bash -c 'pid=""; while [ -z "$pid" ]; do pid=$(pgrep -f oci-logs-plugin); done; /root/go/bin/dlv attach --api-version=2 --headless --continue --accept-multiclient --listen=:2345 $pid' 19 | stdout_logfile=/dev/fd/1 20 | stdout_logfile_maxbytes=0 21 | redirect_stderr=true 22 | killasgroup=false 23 | stopasgroup=false 24 | autostart=true 25 | autorestart=true 26 | 27 | [program:build-watcher] 28 | user=root 29 | command=/bin/bash -c 'while inotifywait -e modify,create,delete -r /var/lib/grafana/plugins/oci-logs-datasource; do echo "Change detected, restarting delve...";supervisorctl restart delve; done' 30 | stdout_logfile=/dev/fd/1 31 | stdout_logfile_maxbytes=0 32 | redirect_stderr=true 33 | killasgroup=true 34 | stopasgroup=true 35 | autostart=true 36 | 37 | [program:mage-watcher] 38 | user=root 39 | environment=PATH="/usr/local/go/bin:/root/go/bin:%(ENV_PATH)s" 40 | directory=/root/oci-logs-datasource 41 | command=/bin/bash -c 'git config --global --add safe.directory /root/oci-logs-datasource && mage -v watch' 42 | stdout_logfile=/dev/fd/1 43 | stdout_logfile_maxbytes=0 44 | redirect_stderr=true 45 | killasgroup=true 46 | stopasgroup=true 47 | autostart=true 48 | -------------------------------------------------------------------------------- /.config/tsconfig.json: -------------------------------------------------------------------------------- 1 | /* 2 | * ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️ 3 | * 4 | * In order to extend the configuration follow the steps in 5 | * https://grafana.com/developers/plugin-tools/create-a-plugin/extend-a-plugin/extend-configurations#extend-the-typescript-config 6 | */ 7 | { 8 | "compilerOptions": { 9 | "alwaysStrict": true, 10 | "declaration": false, 11 | "rootDir": "../src", 12 | "baseUrl": "../src", 13 | "typeRoots": ["../node_modules/@types"], 14 | "resolveJsonModule": true 15 | }, 16 | "ts-node": { 17 | "compilerOptions": { 18 | "module": "commonjs", 19 | "target": "es5", 20 | "esModuleInterop": true 21 | }, 22 | "transpileOnly": true 23 | }, 24 | "include": ["../src", "./types"], 25 | "extends": "@grafana/tsconfig" 26 | } 27 | -------------------------------------------------------------------------------- /.config/types/custom.d.ts: -------------------------------------------------------------------------------- 1 | // Image declarations 2 | declare module '*.gif' { 3 | const src: string; 4 | export default src; 5 | } 6 | 7 | declare module '*.jpg' { 8 | const src: string; 9 | export default src; 10 | } 11 | 12 | declare module '*.jpeg' { 13 | const src: string; 14 | export default src; 15 | } 16 | 17 | declare module '*.png' { 18 | const src: string; 19 | export default src; 20 | } 21 | 22 | declare module '*.webp' { 23 | const src: string; 24 | export default src; 25 | } 26 | 27 | declare module '*.svg' { 28 | const content: string; 29 | export default content; 30 | } 31 | 32 | // Font declarations 33 | declare module '*.woff'; 34 | declare module '*.woff2'; 35 | declare module '*.eot'; 36 | declare module '*.ttf'; 37 | declare module '*.otf'; 38 | -------------------------------------------------------------------------------- /.config/webpack/constants.ts: -------------------------------------------------------------------------------- 1 | export const SOURCE_DIR = 'src'; 2 | export const DIST_DIR = 'dist'; 3 | -------------------------------------------------------------------------------- /.config/webpack/publicPath.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️ 3 | * 4 | * This file dynamically sets the public path at runtime based on the location of the plugin's AMD module. 5 | * It relies on the magic `module` which is defined by the AMD loader. 6 | * https://github.com/requirejs/requirejs/wiki/Differences-between-the-simplified-CommonJS-wrapper-and-standard-AMD-define#module 7 | * 8 | * We fallback to the plugin root so that older versions of Grafana will continue to load the plugin correctly. 9 | */ 10 | 11 | // @ts-nocheck 12 | import amdMetaModule from 'amd-module'; 13 | 14 | __webpack_public_path__ = 15 | amdMetaModule && amdMetaModule.uri 16 | ? amdMetaModule.uri.slice(0, amdMetaModule.uri.lastIndexOf('/') + 1) 17 | : 'public/plugins/oci-logs-datasource/'; 18 | -------------------------------------------------------------------------------- /.config/webpack/utils.ts: -------------------------------------------------------------------------------- 1 | import fs from 'fs'; 2 | import process from 'process'; 3 | import os from 'os'; 4 | import path from 'path'; 5 | import { glob } from 'glob'; 6 | import { SOURCE_DIR } from './constants'; 7 | 8 | export function isWSL() { 9 | if (process.platform !== 'linux') { 10 | return false; 11 | } 12 | 13 | if (os.release().toLowerCase().includes('microsoft')) { 14 | return true; 15 | } 16 | 17 | try { 18 | return fs.readFileSync('/proc/version', 'utf8').toLowerCase().includes('microsoft'); 19 | } catch { 20 | return false; 21 | } 22 | } 23 | 24 | export function getPackageJson() { 25 | return require(path.resolve(process.cwd(), 'package.json')); 26 | } 27 | 28 | export function getPluginJson() { 29 | return require(path.resolve(process.cwd(), `${SOURCE_DIR}/plugin.json`)); 30 | } 31 | 32 | export function getCPConfigVersion() { 33 | const cprcJson = path.resolve(__dirname, '../', '.cprc.json'); 34 | return fs.existsSync(cprcJson) ? require(cprcJson).version : { version: 'unknown' }; 35 | } 36 | 37 | export function hasReadme() { 38 | return fs.existsSync(path.resolve(process.cwd(), SOURCE_DIR, 'README.md')); 39 | } 40 | 41 | // Support bundling nested plugins by finding all plugin.json files in src directory 42 | // then checking for a sibling module.[jt]sx? file. 43 | export async function getEntries(): Promise> { 44 | const pluginsJson = await glob('**/src/**/plugin.json', { absolute: true }); 45 | 46 | const plugins = await Promise.all( 47 | pluginsJson.map((pluginJson) => { 48 | const folder = path.dirname(pluginJson); 49 | return glob(`${folder}/module.{ts,tsx,js,jsx}`, { absolute: true }); 50 | }) 51 | ); 52 | 53 | return plugins.reduce((result, modules) => { 54 | return modules.reduce((result, module) => { 55 | const pluginPath = path.dirname(module); 56 | const pluginName = path.relative(process.cwd(), pluginPath).replace(/src\/?/i, ''); 57 | const entryName = pluginName === '' ? 'module' : `${pluginName}/module`; 58 | 59 | result[entryName] = module; 60 | return result; 61 | }, result); 62 | }, {}); 63 | } 64 | -------------------------------------------------------------------------------- /.config/webpack/webpack.config.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️ 3 | * 4 | * In order to extend the configuration follow the steps in 5 | * https://grafana.com/developers/plugin-tools/create-a-plugin/extend-a-plugin/extend-configurations#extend-the-webpack-config 6 | */ 7 | 8 | import CopyWebpackPlugin from 'copy-webpack-plugin'; 9 | import ESLintPlugin from 'eslint-webpack-plugin'; 10 | import ForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin'; 11 | import LiveReloadPlugin from 'webpack-livereload-plugin'; 12 | import path from 'path'; 13 | import ReplaceInFileWebpackPlugin from 'replace-in-file-webpack-plugin'; 14 | import TerserPlugin from 'terser-webpack-plugin'; 15 | import { type Configuration, BannerPlugin } from 'webpack'; 16 | 17 | import { getPackageJson, getPluginJson, hasReadme, getEntries, isWSL, getCPConfigVersion } from './utils'; 18 | import { SOURCE_DIR, DIST_DIR } from './constants'; 19 | 20 | const pluginJson = getPluginJson(); 21 | const cpVersion = getCPConfigVersion(); 22 | 23 | const config = async (env): Promise => { 24 | const baseConfig: Configuration = { 25 | cache: { 26 | type: 'filesystem', 27 | buildDependencies: { 28 | config: [__filename], 29 | }, 30 | }, 31 | 32 | context: path.join(process.cwd(), SOURCE_DIR), 33 | 34 | devtool: env.production ? 'source-map' : 'eval-source-map', 35 | 36 | entry: await getEntries(), 37 | 38 | externals: [ 39 | // Required for dynamic publicPath resolution 40 | { 'amd-module': 'module' }, 41 | 'lodash', 42 | 'jquery', 43 | 'moment', 44 | 'slate', 45 | 'emotion', 46 | '@emotion/react', 47 | '@emotion/css', 48 | 'prismjs', 49 | 'slate-plain-serializer', 50 | '@grafana/slate-react', 51 | 'react', 52 | 'react-dom', 53 | 'react-redux', 54 | 'redux', 55 | 'rxjs', 56 | 'react-router', 57 | 'react-router-dom', 58 | 'd3', 59 | 'angular', 60 | '@grafana/ui', 61 | '@grafana/runtime', 62 | '@grafana/data', 63 | 64 | // Mark legacy SDK imports as external if their name starts with the "grafana/" prefix 65 | ({ request }, callback) => { 66 | const prefix = 'grafana/'; 67 | const hasPrefix = (request) => request.indexOf(prefix) === 0; 68 | const stripPrefix = (request) => request.substr(prefix.length); 69 | 70 | if (hasPrefix(request)) { 71 | return callback(undefined, stripPrefix(request)); 72 | } 73 | 74 | callback(); 75 | }, 76 | ], 77 | 78 | // Support WebAssembly according to latest spec - makes WebAssembly module async 79 | experiments: { 80 | asyncWebAssembly: true, 81 | }, 82 | 83 | mode: env.production ? 'production' : 'development', 84 | 85 | module: { 86 | rules: [ 87 | { 88 | exclude: /(node_modules)/, 89 | test: /\.[tj]sx?$/, 90 | use: { 91 | loader: 'swc-loader', 92 | options: { 93 | jsc: { 94 | baseUrl: path.resolve(process.cwd(), SOURCE_DIR), 95 | target: 'es2015', 96 | loose: false, 97 | parser: { 98 | syntax: 'typescript', 99 | tsx: true, 100 | decorators: false, 101 | dynamicImport: true, 102 | }, 103 | }, 104 | }, 105 | }, 106 | }, 107 | { 108 | test: /src\/(?:.*\/)?module\.tsx?$/, 109 | use: [ 110 | { 111 | loader: 'imports-loader', 112 | options: { 113 | imports: `side-effects ${path.join(__dirname, 'publicPath.ts')}`, 114 | }, 115 | }, 116 | ], 117 | }, 118 | { 119 | test: /\.css$/, 120 | use: ['style-loader', 'css-loader'], 121 | }, 122 | { 123 | test: /\.s[ac]ss$/, 124 | use: ['style-loader', 'css-loader', 'sass-loader'], 125 | }, 126 | { 127 | test: /\.(png|jpe?g|gif|svg)$/, 128 | type: 'asset/resource', 129 | generator: { 130 | filename: Boolean(env.production) ? '[hash][ext]' : '[file]', 131 | }, 132 | }, 133 | { 134 | test: /\.(woff|woff2|eot|ttf|otf)(\?v=\d+\.\d+\.\d+)?$/, 135 | type: 'asset/resource', 136 | generator: { 137 | filename: Boolean(env.production) ? '[hash][ext]' : '[file]', 138 | }, 139 | }, 140 | ], 141 | }, 142 | 143 | optimization: { 144 | minimize: Boolean(env.production), 145 | minimizer: [ 146 | new TerserPlugin({ 147 | terserOptions: { 148 | format: { 149 | comments: (_, { type, value }) => type === 'comment2' && value.trim().startsWith('[create-plugin]'), 150 | }, 151 | }, 152 | }), 153 | ], 154 | }, 155 | 156 | output: { 157 | clean: { 158 | keep: new RegExp(`(.*?_(amd64|arm(64)?)(.exe)?|go_plugin_build_manifest)`), 159 | }, 160 | filename: '[name].js', 161 | library: { 162 | type: 'amd', 163 | }, 164 | path: path.resolve(process.cwd(), DIST_DIR), 165 | publicPath: `public/plugins/${pluginJson.id}/`, 166 | uniqueName: pluginJson.id, 167 | }, 168 | 169 | plugins: [ 170 | // Insert create plugin version information into the bundle 171 | new BannerPlugin({ 172 | banner: '/* [create-plugin] version: ' + cpVersion + ' */', 173 | raw: true, 174 | entryOnly: true, 175 | }), 176 | new CopyWebpackPlugin({ 177 | patterns: [ 178 | // If src/README.md exists use it; otherwise the root README 179 | // To `compiler.options.output` 180 | { from: hasReadme() ? 'README.md' : '../README.md', to: '.', force: true }, 181 | { from: 'plugin.json', to: '.' }, 182 | { from: '../LICENSE', to: '.' }, 183 | { from: '../CHANGELOG.md', to: '.', force: true }, 184 | { from: '**/*.json', to: '.' }, // TODO 185 | { from: '**/*.svg', to: '.', noErrorOnMissing: true }, // Optional 186 | { from: '**/*.png', to: '.', noErrorOnMissing: true }, // Optional 187 | { from: '**/*.html', to: '.', noErrorOnMissing: true }, // Optional 188 | { from: 'img/**/*', to: '.', noErrorOnMissing: true }, // Optional 189 | { from: 'libs/**/*', to: '.', noErrorOnMissing: true }, // Optional 190 | { from: 'static/**/*', to: '.', noErrorOnMissing: true }, // Optional 191 | { from: '**/query_help.md', to: '.', noErrorOnMissing: true }, // Optional 192 | ], 193 | }), 194 | // Replace certain template-variables in the README and plugin.json 195 | new ReplaceInFileWebpackPlugin([ 196 | { 197 | dir: DIST_DIR, 198 | files: ['plugin.json', 'README.md'], 199 | rules: [ 200 | { 201 | search: /\%VERSION\%/g, 202 | replace: getPackageJson().version, 203 | }, 204 | { 205 | search: /\%TODAY\%/g, 206 | replace: new Date().toISOString().substring(0, 10), 207 | }, 208 | { 209 | search: /\%PLUGIN_ID\%/g, 210 | replace: pluginJson.id, 211 | }, 212 | ], 213 | }, 214 | ]), 215 | ...(env.development 216 | ? [ 217 | new LiveReloadPlugin(), 218 | new ForkTsCheckerWebpackPlugin({ 219 | async: Boolean(env.development), 220 | issue: { 221 | include: [{ file: '**/*.{ts,tsx}' }], 222 | }, 223 | typescript: { configFile: path.join(process.cwd(), 'tsconfig.json') }, 224 | }), 225 | new ESLintPlugin({ 226 | extensions: ['.ts', '.tsx'], 227 | lintDirtyModulesOnly: Boolean(env.development), // don't lint on start, only lint changed files 228 | }), 229 | ] 230 | : []), 231 | ], 232 | 233 | resolve: { 234 | extensions: ['.js', '.jsx', '.ts', '.tsx'], 235 | // handle resolving "rootDir" paths 236 | modules: [path.resolve(process.cwd(), 'src'), 'node_modules'], 237 | unsafeCache: true, 238 | }, 239 | }; 240 | 241 | if (isWSL()) { 242 | baseConfig.watchOptions = { 243 | poll: 3000, 244 | ignored: /node_modules/, 245 | }; 246 | } 247 | 248 | return baseConfig; 249 | }; 250 | 251 | export default config; 252 | -------------------------------------------------------------------------------- /.cprc.json: -------------------------------------------------------------------------------- 1 | { 2 | "features": { 3 | "bundleGrafanaUI": false, 4 | "useReactRouterV6": false 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./.config/.eslintrc" 3 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 2 | *.o 3 | *.a 4 | *.so 5 | 6 | # Folders 7 | _obj 8 | _test 9 | 10 | # Architecture specific extensions/prefixes 11 | *.[568vq] 12 | [568vq].out 13 | 14 | *.cgo1.go 15 | *.cgo2.c 16 | _cgo_defun.c 17 | _cgo_gotypes.go 18 | _cgo_export.* 19 | 20 | _testmain.go 21 | 22 | *.exe 23 | *.test 24 | *.prof 25 | 26 | /vendor/** 27 | !/vendor/vendor.json 28 | .DS_Store 29 | *.swp 30 | 31 | node_modules 32 | .yarn 33 | oci-logs-datasource 34 | dist/oci-plugin_* 35 | coverage/ 36 | dist/ 37 | *_orig 38 | .idea 39 | 40 | #Ignore the built tar and zip files 41 | *.tar 42 | *.zip 43 | 44 | yarn-error.log 45 | 46 | # Logs 47 | logs 48 | *.log 49 | npm-debug.log* 50 | yarn-debug.log* 51 | yarn-error.log* 52 | 53 | node_modules/ 54 | 55 | # Runtime data 56 | pids 57 | *.pid 58 | *.seed 59 | *.pid.lock 60 | 61 | # Directory for instrumented libs generated by jscoverage/JSCover 62 | lib-cov 63 | 64 | # Coverage directory used by tools like istanbul 65 | coverage 66 | 67 | # Compiled binary addons (https://nodejs.org/api/addons.html) 68 | dist/ 69 | artifacts/ 70 | work/ 71 | ci/ 72 | e2e-results/ 73 | 74 | # Editor 75 | .idea 76 | .vscode 77 | 78 | 79 | .codegpt -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | 16 -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | // Prettier configuration provided by Grafana scaffolding 3 | ...require("./.config/.prettierrc.js") 4 | }; -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/.vscode/settings.json -------------------------------------------------------------------------------- /.yarnrc.yml: -------------------------------------------------------------------------------- 1 | nodeLinker: node-modules 2 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | 2 | # [Security Maintenance release (v5.0.2)](https://github.com/oracle/oci-grafana-metrics/releases/tag/v5.0.2) - 26 Nov 2024 3 | 4 | This release includes: 5 | 6 | - Bug fix for github issue 117 7 | - Bump cross-spawn from 7.0.3 to 7.0.6 8 | 9 | [Changes][v5.0.2] 10 | 11 | 12 | # [Security Maintenance release (v5.0.1)](https://github.com/oracle/oci-grafana-metrics/releases/tag/v5.0.1) - 14 Oct 2024 13 | 14 | This release includes: 15 | 16 | - security patches 17 | - Added new regions 18 | 19 | [Changes][v5.0.1] 20 | 21 | 22 | # [Grafana 11 support and free query template vars (v5.0.0)](https://github.com/oracle/oci-grafana-logs/releases/tag/v5.0.0) - 03 Sep 2024 23 | 24 | This release includes: 25 | - Grafana 11 Support, drop support for Grafana 8.x 26 | - React 18 library upgraded 27 | - Support for free query template variable 28 | - Enhanced debug logs 29 | - Libraries upgrades and minor bug and security fixes 30 | 31 | [Changes][v5.0.0] 32 | 33 | 34 | 35 | # [Sovereign cloud support and minor fixes (v4.0.2)](https://github.com/oracle/oci-grafana-logs/releases/tag/v4.0.2) - 28 Mar 2024 36 | 37 | This release includes: 38 | - Sovereign cloud Support 39 | - Bug fix in Explore function 40 | - Grafana and OCI SDK libraries upgrades 41 | 42 | [Changes][v4.0.2] 43 | 44 | 45 | 46 | # [Added new regions to the oci datasource plugin (v4.0.1)](https://github.com/oracle/oci-grafana-logs/releases/tag/v4.0.1) - 20 Feb 2024 47 | 48 | 49 | 50 | [Changes][v4.0.1] 51 | 52 | 53 | 54 | # [Grafana 10 support (v4.0.0)](https://github.com/oracle/oci-grafana-logs/releases/tag/v4.0.0) - 31 Oct 2023 55 | 56 | - FE completely rewritten in React/Typescript 57 | - Compatibility with Grafana 10 58 | - Caching of region, tenancy, compartments, dimensions queries 59 | - many performance improvements 60 | - new Grafana API 61 | 62 | [Changes][v4.0.0] 63 | 64 | 65 | 66 | # [Multi-tenancy support and Secure JSON for OCI (v3.0.0)](https://github.com/oracle/oci-grafana-logs/releases/tag/v3.0.0) - 27 Mar 2023 67 | 68 | This release features 69 | 70 | - Multi-tenancy support 71 | - Secure JSON secrets for OCI Configuration 72 | - Added support for San Jose region 73 | 74 | [Changes][v3.0.0] 75 | 76 | 77 | 78 | # [Region list sort and vulnerability patches (v2.0.3)](https://github.com/oracle/oci-grafana-logs/releases/tag/v2.0.3) - 24 Oct 2022 79 | 80 | - Region list sort (https://github.com/oracle/oci-grafana-logs/pull/42) 81 | - Vulnerability patches (https://github.com/oracle/oci-grafana-logs/pull/43, https://github.com/oracle/oci-grafana-logs/pull/44, https://github.com/oracle/oci-grafana-logs/pull/46, https://github.com/oracle/oci-grafana-logs/pull/48) 82 | 83 | [Changes][v2.0.3] 84 | 85 | 86 | 87 | # [Feature Enhancements/Bug Fixes/ARM Support (v2.0.2)](https://github.com/oracle/oci-grafana-logs/releases/tag/v2.0.2) - 31 Aug 2022 88 | 89 | * Documentations updates for OCI Grafana Logs PR [#39](https://github.com/oracle/oci-grafana-logs/issues/39) 90 | * Support of OCI-Logging rounddown function PR [#38](https://github.com/oracle/oci-grafana-logs/issues/38) 91 | * Pagination support and log search improvements PR [#32](https://github.com/oracle/oci-grafana-logs/issues/32) PR [#24](https://github.com/oracle/oci-grafana-logs/issues/24) 92 | * Bug fixes around numeric math PR [#35](https://github.com/oracle/oci-grafana-logs/issues/35) PR [#37](https://github.com/oracle/oci-grafana-logs/issues/37) 93 | * Logs Presentation improvements PR [#26](https://github.com/oracle/oci-grafana-logs/issues/26) 94 | 95 | [Changes][v2.0.2] 96 | 97 | 98 | 99 | # [Minor update (v2.0.1)](https://github.com/oracle/oci-grafana-logs/releases/tag/v2.0.1) - 16 Mar 2022 100 | 101 | Update plugin.json, update screenshots 102 | 103 | [Changes][v2.0.1] 104 | 105 | 106 | 107 | # [Grafana 8 support (v2.0.0)](https://github.com/oracle/oci-grafana-logs/releases/tag/v2.0.0) - 25 Feb 2022 108 | 109 | - Support for Grafana 8, will not work in Grafana 7. 110 | - Search query queries triggers fixed. 111 | - Test data source will always succeed, will be revamped in the future. 112 | - Fix for table view 113 | 114 | [Changes][v2.0.0] 115 | 116 | 117 | 118 | # [Test package or PR 4 (v1.1.3-beta)](https://github.com/oracle/oci-grafana-logs/releases/tag/v1.1.3-beta) - 04 Feb 2021 119 | 120 | - Details will be updated once PR4 is released. 121 | 122 | [Changes][v1.1.3-beta] 123 | 124 | [v5.0.2]: https://github.com/oracle/oci-grafana-logs/compare/v5.0.1...v5.0.2 125 | [v5.0.1]: https://github.com/oracle/oci-grafana-logs/compare/v5.0.0...v5.0.1 126 | [v5.0.0]: https://github.com/oracle/oci-grafana-logs/compare/v4.0.2...v5.0.0 127 | [v4.0.2]: https://github.com/oracle/oci-grafana-logs/compare/v4.0.1...v4.0.2 128 | [v4.0.1]: https://github.com/oracle/oci-grafana-logs/compare/v4.0.0...v4.0.1 129 | [v4.0.0]: https://github.com/oracle/oci-grafana-logs/compare/v3.0.0...v4.0.0 130 | [v3.0.0]: https://github.com/oracle/oci-grafana-logs/compare/v2.0.3...v3.0.0 131 | [v2.0.3]: https://github.com/oracle/oci-grafana-logs/compare/v2.0.2...v2.0.3 132 | [v2.0.2]: https://github.com/oracle/oci-grafana-logs/compare/v2.0.1...v2.0.2 133 | [v2.0.1]: https://github.com/oracle/oci-grafana-logs/compare/v2.0.0...v2.0.1 134 | [v2.0.0]: https://github.com/oracle/oci-grafana-logs/compare/v1.1.3-beta...v2.0.0 135 | [v1.1.3-beta]: https://github.com/oracle/oci-grafana-logs/tree/v1.1.3-beta 136 | 137 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to this repository 2 | 3 | We welcome your contributions! There are multiple ways to contribute. 4 | 5 | ## Opening issues 6 | 7 | For bugs or enhancement requests, please file a GitHub issue unless it's 8 | security related. When filing a bug remember that the better written the bug is, 9 | the more likely it is to be fixed. If you think you've found a security 10 | vulnerability, do not raise a GitHub issue and follow the instructions in our 11 | [security policy](./SECURITY.md). 12 | 13 | ## Contributing code 14 | 15 | We welcome your code contributions. Before submitting code via a pull request, 16 | you will need to have signed the [Oracle Contributor Agreement][OCA] (OCA) and 17 | your commits need to include the following line using the name and e-mail 18 | address you used to sign the OCA: 19 | 20 | ```text 21 | Signed-off-by: Your Name 22 | ``` 23 | 24 | This can be automatically added to pull requests by committing with `--sign-off` 25 | or `-s`, e.g. 26 | 27 | ```text 28 | git commit --signoff 29 | ``` 30 | 31 | Only pull requests from committers that can be verified as having signed the OCA 32 | can be accepted. 33 | 34 | ## Pull request process 35 | 36 | 1. Ensure there is an issue created to track and discuss the fix or enhancement 37 | you intend to submit. 38 | 1. Fork this repository. 39 | 1. Create a branch in your fork to implement the changes. We recommend using 40 | the issue number as part of your branch name, e.g. `1234-fixes`. 41 | 1. Ensure that any documentation is updated with the changes that are required 42 | by your change. 43 | 1. Ensure that any samples are updated if the base image has been changed. 44 | 1. Submit the pull request. *Do not leave the pull request blank*. Explain exactly 45 | what your changes are meant to do and provide simple steps on how to validate. 46 | your changes. Ensure that you reference the issue you created as well. 47 | 1. We will assign the pull request to 2-3 people for review before it is merged. 48 | 49 | ## Code of conduct 50 | 51 | Follow the [Golden Rule](https://en.wikipedia.org/wiki/Golden_Rule). If you'd 52 | like more specific guidelines, see the [Contributor Covenant Code of Conduct][COC]. 53 | 54 | [OCA]: https://oca.opensource.oracle.com 55 | [COC]: https://www.contributor-covenant.org/version/1/4/code-of-conduct/ 56 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2021 Oracle and/or its affiliates. 2 | 3 | The Universal Permissive License (UPL), Version 1.0 4 | 5 | Subject to the condition set forth below, permission is hereby granted to any 6 | person obtaining a copy of this software, associated documentation and/or data 7 | (collectively the "Software"), free of charge and under any and all copyright 8 | rights in the Software, and any and all patent rights owned or freely 9 | licensable by each licensor hereunder covering either (i) the unmodified 10 | Software as contributed to or provided by such licensor, or (ii) the Larger 11 | Works (as defined below), to deal in both 12 | 13 | (a) the Software, and 14 | (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if 15 | one is included with the Software (each a "Larger Work" to which the Software 16 | is contributed by such licensors), 17 | 18 | without restriction, including without limitation the rights to copy, create 19 | derivative works of, display, perform, and distribute the Software and make, 20 | use, sell, offer for sale, import, export, have made, and have sold the 21 | Software and the Larger Work(s), and to sublicense the foregoing rights on 22 | either these or other terms. 23 | 24 | This license is subject to the following condition: 25 | The above copyright notice and either this complete permission notice or at 26 | a minimum a reference to the UPL must be included in all copies or 27 | substantial portions of the Software. 28 | 29 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 30 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 31 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 32 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 33 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 34 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 35 | SOFTWARE. 36 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2021 Oracle and/or its affiliates. 2 | 3 | The Universal Permissive License (UPL), Version 1.0 4 | 5 | Subject to the condition set forth below, permission is hereby granted to any 6 | person obtaining a copy of this software, associated documentation and/or data 7 | (collectively the "Software"), free of charge and under any and all copyright 8 | rights in the Software, and any and all patent rights owned or freely 9 | licensable by each licensor hereunder covering either (i) the unmodified 10 | Software as contributed to or provided by such licensor, or (ii) the Larger 11 | Works (as defined below), to deal in both 12 | 13 | (a) the Software, and 14 | (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if 15 | one is included with the Software (each a "Larger Work" to which the Software 16 | is contributed by such licensors), 17 | 18 | without restriction, including without limitation the rights to copy, create 19 | derivative works of, display, perform, and distribute the Software and make, 20 | use, sell, offer for sale, import, export, have made, and have sold the 21 | Software and the Larger Work(s), and to sublicense the foregoing rights on 22 | either these or other terms. 23 | 24 | This license is subject to the following condition: 25 | The above copyright notice and either this complete permission notice or at 26 | a minimum a reference to the UPL must be included in all copies or 27 | substantial portions of the Software. 28 | 29 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 30 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 31 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 32 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 33 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 34 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 35 | SOFTWARE. 36 | -------------------------------------------------------------------------------- /Magefile.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2022 Oracle and/or its affiliates. All rights reserved. 2 | // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. 3 | 4 | //go:build mage 5 | 6 | package main 7 | 8 | import ( 9 | "fmt" 10 | "os" 11 | 12 | // mage:import 13 | build "github.com/grafana/grafana-plugin-sdk-go/build" 14 | ) 15 | 16 | // Default configures the default target. 17 | var Default = build.BuildAll 18 | 19 | // Cleans up local folder 20 | func CleanLocal() error { 21 | fmt.Println("Cleans the local folder") 22 | err := os.RemoveAll("oci-logs-datasource/") 23 | if err != nil { 24 | fmt.Println(err) 25 | } 26 | return err 27 | 28 | } 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Oracle Cloud Infrastructure Logging Data Source 2 | 3 | ## Introduction 4 | 5 | Grafana is a popular technology that makes it easy to visualize logs and metrics. 6 | The OCI Logging Grafana Plugin can be used to extend Grafana by adding 7 | [Oracle Cloud Infrastructure Logging][1] as a data source in Grafana. 8 | 9 | The plugin allows you to retrieve logs related to a number of resources on 10 | Oracle Cloud: Compute, Networking, Storage, custom logs from your application, 11 | and audit logs generated by Oracle Cloud services. Once these logs are in Grafana, 12 | they can be analyzed along with metrics, giving you a single pane of glass for your 13 | application monitoring needs. 14 | 15 | Latest plugin version 4.X.X (available on [Grafana Marketplace](https://grafana.com/grafana/plugins/oci-logs-datasource/)) is compatible with **Grafana 10**. 16 | 17 | Breaking change! 18 | In case you are migrating from a previous version (2.x.x or below) of the OCI Logging Grafana Plugin and are not using Instance Principals (**Authentication Provider** not set as **OCI instance**), please refer to the [**Migration Instructions for Grafana OCI Logging Data Source Settings (User Principals and Single Tenancy mode only)**](https://github.com/oracle/oci-grafana-logs/blob/main/docs/migration.md) because you will have to reconfigure the plugin setup. 19 | 20 | For custom logs from your application, see [Custom Logging on OCI][2]. 21 | ## Prerequisites 22 | 23 | We will discuss two different Grafana IAM configurations that need to be in 24 | place, for Grafana to fetch the logs from Oracle Cloud Logging Service. 25 | 26 | ### For local/dev box environment and Grafana Cloud 27 | 28 | #### Installation 29 | 30 | Please refers to the following **compatibility matrix** to choose plugin version accordingly to your Grafana installation: [Compatibility Matrix](https://github.com/oracle/oci-grafana-logs/blob/Grafana10-support-test/docs/compatmatrix.md) 31 | 32 | In order to simplify the installation process, we created detailed guides for you to follow. 33 | 34 | Depending on your installation scenario you can use the following guides: 35 | 36 | * Install Grafana and the OCI Logs plugin on a Linux host using [this document](https://github.com/oracle/oci-grafana-logs/blob/main/docs/linux.md). 37 | 38 | * Install Grafana and the OCI Logs plugin on Grafana Cloud using [this document](https://github.com/oracle/oci-grafana-logs/blob/main/docs/grafanacloud.md). 39 | 40 | * Install Grafana and the OCI Logs plugin on a MacOS host using [this document](https://github.com/oracle/oci-grafana-logs/blob/main/docs/macos.md). 41 | 42 | 43 | #### Configure OCI Identity Policies 44 | 45 | In the OCI console under **Identity > Groups** click **Create Group** and create 46 | a new group called **GrafanaLoggingUserGroup**. Add the user configured in the 47 | OCI CLI to the newly-created group. 48 | 49 | ![alt text](https://github.com/oracle/oci-grafana-logs/blob/main/docs/images/usrGp.png?raw=true) 50 | 51 | Under the **Policy** tab switch to the root compartment and click **Create Policy**. 52 | Create a policy allowing the group to read tenancy log groups and log content. Add the following 53 | policy statements: 54 | 55 | - `allow group GrafanaLoggingUserGroup to read log-groups in tenancy` 56 | - `allow group GrafanaLoggingUserGroup to read log-content in tenancy` 57 | - `allow group GrafanaLoggingUserGroup to read compartments in tenancy` 58 | 59 | ![alt text](https://github.com/oracle/oci-grafana-logs/blob/main/docs/images/usrPolicy.png?raw=true) 60 | 61 | ### For compute-instance/VM on Oracle Cloud Infrastructure 62 | 63 | #### Create a Dynamic Group for your instance 64 | 65 | Provision an Oracle Linux [virtual machine][7] in OCI connected to a 66 | [Virtual Cloud Network][8] with access to the public internet. If you do not 67 | already have access to a Virtual Cloud Network with access to the public 68 | internet you can navigate to **Virtual Cloud Networks** under **Networking** and 69 | click **Create Virtual Cloud Network**. Choosing the `CREATE VIRTUAL CLOUD NETWORK PLUS RELATED RESOURCES` option will result in a 70 | VCN with an Internet Routing Gateway and Route Tables configured for access to 71 | the public internet. Three subnets will be created: one in each availability 72 | domain in the region. 73 | 74 | After creating your VM, the next step is to create a [dynamic group][9] used to 75 | group virtual machine or bare metal compute instances as “principals” (similar 76 | to user groups). 77 | 78 | You can define the dynamic group similarly to below, where your instance is part 79 | of the compartment given in the definition of the dynamic group. 80 | ![alt text](https://github.com/oracle/oci-grafana-logs/blob/main/docs/images/dgGroup.png?raw=true) 81 | 82 | #### Create an IAM policy for Dynamic Group for your instance 83 | 84 | Next, create a [policy][10] named “grafana_policy” in the root compartment of 85 | your tenancy to permit instances in the dynamic group to make API calls against 86 | Oracle Cloud Infrastructure services. Add the following policy statements: 87 | 88 | - `allow dynamicgroup DynamicGroupForGrafanaInstances to read log-groups in tenancy` 89 | - `allow dynamicgroup DynamicGroupForGrafanaInstances to read log-content in tenancy` 90 | - `allow dynamicgroup DynamicGroupForGrafanaInstances to read compartments in tenancy` 91 | 92 | ![alt text](https://github.com/oracle/oci-grafana-logs/blob/main/docs/images/dgPolicy.png?raw=true) 93 | 94 | #### Installation 95 | 96 | Depending on your installation scenario you can use the following guides: 97 | 98 | * Install Grafana and the OCI Logs plugin on a virtual machine in Oracle Cloud Infrastructure using [this document](https://github.com/oracle/oci-grafana-logs/blob/main/docs/linuxoci.md). 99 | 100 | * Install Grafana and the OCI Logs plugin on a virtual machine in Oracle Cloud Infrastructure using Terraform using [this document](https://github.com/oracle/oci-grafana-logs/blob/main/docs/terraform.md). 101 | 102 | * Install Grafana and the OCI Logs plugin on Kubernetes in Oracle Cloud Infrastructure using [this document](https://github.com/oracle/oci-grafana-logs/blob/main/docs/kubernetes.md) 103 | 104 | 105 | ## Note 1 106 | 107 | The OCI Logs plugin supports the integration with Grafana Cloud with Data Source **Authentication Provider** configured as **local**. See [this document](https://github.com/oracle/oci-grafana-logs/blob/master/docs/grafanacloud.md) for additional information. 108 | 109 | ## Documentation 110 | 111 | Please refer to the [docs folder in this GitHub repository](https://github.com/oracle/oci-grafana-logs/tree/main/docs) for more information on installing and using the OCI Logging data source. 112 | 113 | ## Help 114 | 115 | Issues and questions about this plugin can be posted 116 | [as an issue in this GitHub repository][11]. 117 | 118 | ## Contributing 119 | 120 | This project welcomes contributions from the community. Before submitting a pull request, please [review our contribution guide](./CONTRIBUTING.md) 121 | 122 | ## Security 123 | 124 | Please consult the [security guide](https://github.com/oracle/oci-grafana-logs/blob/main/SECURITY.md) for our responsible security 125 | vulnerability disclosure process. 126 | 127 | ## License 128 | 129 | Copyright (c) 2023 Oracle and/or its affiliates. 130 | 131 | Released under the Universal Permissive License v1.0 as shown at 132 | . 133 | 134 | [1]: https://docs.cloud.oracle.com/en-us/iaas/Content/Logging/Concepts/loggingoverview.htm 135 | [2]: https://docs.cloud.oracle.com/en-us/iaas/Content/Logging/Concepts/custom_logs.htm 136 | [3]: https://docs.cloud.oracle.com/iaas/Content/API/Concepts/cliconcepts.htm 137 | [4]: https://docs.cloud.oracle.com/iaas/Content/API/Concepts/usingapi.htm 138 | [5]: https://docs.cloud.oracle.com/iaas/Content/API/SDKDocs/cliinstall.htm 139 | [6]: https://docs.cloud.oracle.com/iaas/Content/API/Concepts/apisigningkey.htm#How2 140 | [7]: https://docs.cloud.oracle.com/iaas/Content/Compute/Concepts/computeoverview.htm 141 | [8]: https://docs.cloud.oracle.com/iaas/Content/Network/Tasks/managingVCNs.htm 142 | [9]: https://docs.cloud.oracle.com/iaas/Content/Identity/Tasks/managingdynamicgroups.htm 143 | [10]: https://docs.cloud.oracle.com/iaas/Content/Identity/Concepts/policygetstarted.htm 144 | [11]: https://github.com/oracle/oci-grafana-logs/issues 145 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Reporting security vulnerabilities 2 | 3 | Oracle values the independent security research community and believes that 4 | responsible disclosure of security vulnerabilities helps us ensure the security 5 | and privacy of all our users. 6 | 7 | Please do NOT raise a GitHub Issue to report a security vulnerability. If you 8 | believe you have found a security vulnerability, please submit a report to 9 | [secalert_us@oracle.com][1] preferably with a proof of concept. Please review 10 | some additional information on [how to report security vulnerabilities to Oracle][2]. 11 | We encourage people who contact Oracle Security to use email encryption using 12 | [our encryption key][3]. 13 | 14 | We ask that you do not use other channels or contact the project maintainers 15 | directly. 16 | 17 | Non-vulnerability related security issues including ideas for new or improved 18 | security features are welcome on GitHub Issues. 19 | 20 | ## Security updates, alerts and bulletins 21 | 22 | Security updates will be released on a regular cadence. Many of our projects 23 | will typically release security fixes in conjunction with the 24 | Oracle Critical Patch Update program. Additional 25 | information, including past advisories, is available on our [security alerts][4] 26 | page. 27 | 28 | ## Security-related information 29 | 30 | We will provide security related information such as a threat model, considerations 31 | for secure use, or any known security issues in our documentation. Please note 32 | that labs and sample code are intended to demonstrate a concept and may not be 33 | sufficiently hardened for production use. 34 | 35 | [1]: mailto:secalert_us@oracle.com 36 | [2]: https://www.oracle.com/corporate/security-practices/assurance/vulnerability/reporting.html 37 | [3]: https://www.oracle.com/security-alerts/encryptionkey.html 38 | [4]: https://www.oracle.com/security-alerts/ 39 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #Do grunt work 4 | # nvm install 12.20 5 | # nvm use 12.20 6 | 7 | if [[ ! -d ./node_modules ]]; then 8 | echo "dependencies not installed try running: yarn" 9 | exit 1 10 | fi 11 | rm -rf ./oci-logs-datasource 12 | rm ./oci-logs-datasource.zip 13 | rm ./plugin.tar 14 | # yarn create @grafana/plugin 15 | yarn run build 16 | if [ $? -ne 0 ]; then 17 | echo "yarn returned error" 18 | exit 1 19 | fi 20 | 21 | mage --debug -v 22 | 23 | cp LICENSE.txt ./dist/LICENSE 24 | 25 | if [ -z $1 ]; then 26 | echo "sign argument not specified, continuing without sign the plugin" 27 | else 28 | if [ $1 = "sign" ]; then 29 | npx @grafana/sign-plugin 30 | else 31 | echo "Usage: ./build.sh " 32 | fi 33 | fi 34 | 35 | mv ./dist ./oci-logs-datasource 36 | tar cvf plugin.tar ./oci-logs-datasource 37 | zip -r oci-logs-datasource ./oci-logs-datasource 38 | 39 | # Instructions for signing 40 | # Please make sure 41 | # nvm install 12.20 42 | 43 | # nvm use 12.20 44 | 45 | # yarn 46 | # For grafana publishing 47 | # yarn install --pure-lockfile && yarn build 48 | # 49 | # Please make sure if you have the api keys installed in bash profile in name, GRAFANA_API_KEY 50 | # Note : Please make sure that you are running the commands in a non-proxy env and without vpn, else grafana signing might fail" 51 | # yarn global add @grafana/toolkit 52 | # grafana-toolkit plugin:sign 53 | 54 | -------------------------------------------------------------------------------- /build_spec.yaml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023, 2022 year, Oracle and/or its affiliates. 2 | 3 | version: 0.1 4 | component: build 5 | timeoutInSeconds: 1000 6 | shell: bash 7 | 8 | steps: 9 | - type: Command 10 | name: "compress the repo" 11 | command: | 12 | tar -cvzf ${OCI_WORKSPACE_DIR}/repo.tgz ./ 13 | outputArtifacts: 14 | - name: artifact 15 | type: BINARY 16 | location: ${OCI_WORKSPACE_DIR}/repo.tgz 17 | -------------------------------------------------------------------------------- /docs/compatmatrix.md: -------------------------------------------------------------------------------- 1 | # OCI Logging Grafana Plugin Compatibility Matrix 2 | 3 | Welcome to the OCI Logging Grafana Plugin Compatibility Matrix page. This document provides information about the compatibility between different versions of the OCI Logging Grafana Plugin and Grafana. Ensuring that you are using compatible versions of these software components is essential for a seamless experience while monitoring your OCI (Oracle Cloud Infrastructure) resources. 4 | 5 | Please refer to the table below for details on which OCI Logging Grafana Plugin version is compatible with which Grafana version. This information is subject to change with future releases, so it's advisable to check the official documentation for the most up-to-date compatibility details. 6 | 7 | **Note:** It's recommended to regularly update your OCI Logging Grafana Plugin and Grafana to take advantage of new features, bug fixes, and security enhancements. 8 | 9 | --- 10 | | OCI Logging Grafana Plugin Version | Grafana Version Compatibility | 11 | |---------------------------|------------------------------| 12 | | 1.1.x | 7.x.x - 7.5.x | 13 | | 2.0.x | 8.0.0 - 8.4.x | 14 | | 3.0.x | 8.5.0 - 9.5.x | 15 | | 4.0.x | 8.5.0 - Latest | 16 | 17 | 18 | > Note: This compatibility matrix is subject to change with future releases. Always refer to the official documentation for the most up-to-date information on compatibility. 19 | 20 | ## References 21 | 22 | Here are some helpful links and references to learn more about OCI Logging Grafana Plugin and Grafana: 23 | 24 | - **OCI Logging Grafana Plugin Official Documentation:** Visit the [OCI Logging Grafana Plugin documentation](https://github.com/oracle/oci-grafana-logs/blob/master/README.md) for in-depth information on installation, configuration, and usage. 25 | 26 | - **Grafana Official Website:** Explore the [Grafana website](https://grafana.com/) to access Grafana's official documentation, plugins, and community resources. 27 | 28 | - **Oracle Cloud Infrastructure (OCI) Official Website:** For information about Oracle Cloud Infrastructure (OCI) and its capabilities, please visit the [OCI website](https://www.oracle.com/cloud/). 29 | 30 | - **GitHub Repositories:** 31 | - [OCI Logging Grafana Plugin GitHub Repository](https://github.com/oracle/oci-grafana-logs): Find the latest releases, source code, and issue tracking for the OCI Logging Grafana Plugin. 32 | - [Grafana GitHub Repository](https://github.com/grafana/grafana): Access Grafana's source code and contribute to the project. 33 | 34 | --- 35 | 36 | Feel free to explore the provided references for detailed information and updates related to OCI Logging Grafana Plugin and Grafana. If you have any questions or encounter compatibility issues, please consult the official documentation or seek assistance from the respective communities and support channels. -------------------------------------------------------------------------------- /docs/grafanacloud.md: -------------------------------------------------------------------------------- 1 | # Grafana Cloud - Oracle Cloud Infrastructure Data Source for Grafana 2 | 3 | ## Background 4 | 5 | Grafana is a popular technology that makes it easy to visualize logs. The [Oracle Cloud Infrastructure Logs Data Source for Grafana](https://grafana.com/grafana/plugins/oci-logs-datasource/) is used to extend Grafana by adding OCI Logging as a data source. The plugin enables you to visualize log records (service, audit, and custom) and Logging derived from log records stored in the OCI Logging service. 6 | 7 | This walkthrough is intended for use by people who would like to deploy Grafana and the OCI Logs Data Source in Grafana Cloud. 8 | 9 | Make sure you have access to the [Logging Service](https://docs.oracle.com/en-us/iaas/Content/Logging/Concepts/loggingoverview.htm) and that the logs you want to observe and analyze are being collected in your tenancy. See the OCI Logging documentation for information on how to collect or access: 10 | * [Logs from your compute instances](https://docs.oracle.com/en-us/iaas/Content/Logging/Concepts/agent_management.htm) 11 | * [Custom logs from your application/services](https://docs.oracle.com/en-us/iaas/Content/Logging/Concepts/custom_logs.htm) 12 | * [OCI service logs](https://docs.oracle.com/en-us/iaas/Content/Logging/Concepts/service_logs.htm). 13 | 14 | ## Getting OCI Configuration values 15 | 16 | To configure OCI Logging Grafana Data Source, you'll need to get the necessary provider and resource settings. Please note that Migrating from version 2.x.x to 3.x.x will require migrating the existing data source configuration: using version 3.x.x of the plugin with the data source configuration of version 2.x.x is **not possible**. In case you are migrating from previous version 2.x.x of the OCI Logging Grafana Plugin, you can refer to the [**Migration Instructions for Grafana OCI Logging Data Source Settings (User Principals and Single Tenancy mode only)**](migration.md). If you are configuring the plugin to work in Multitenancy Mode, you will need to repeat the following steps for each of the Tenancies you want to configure with the plugin (up to 5 additional Tenancies are supported). 17 | 18 | ### Getting the Region 19 | 20 | To get the region for your OCI cloud, follow these steps: 21 | 22 | 1. Log in to the OCI console. 23 | 2. From the OCI menu, select the **Region** dropdown in the top right corner of the page. 24 | 3. The region is listed next to **Home**. 25 | 26 | For details and reference, see: [Regions and Availability Domains](https://docs.oracle.com/en-us/iaas/Content/General/Concepts/regions.htm#top) 27 | Please make note of the region as you'll need it later to configure your OCI Logging Grafana Data Source. 28 | 29 | ### Getting the Tenancy OCID 30 | 31 | To get the tenancy OCID, follow these steps: 32 | 33 | 1. Log in to the OCI console. 34 | 2. From the OCI menu, click on your profile icon on the top right: 35 | 36 | ![OCI Administration](images/oci_administration.png) 37 | 38 | 3. Click on Tenancy 39 | 4. The tenancy OCID is listed in the **Tenancy Information** section. 40 | 41 | ![OCI Tenancy](images/oci_tenancy.png) 42 | 43 | For details and reference, see: [Where to Get the Tenancy's OCID and User's OCID](https://docs.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm#five) 44 | Please make note of the tenancy OCID as you'll need it later to configure your OCI Logging Grafana Data Source. 45 | 46 | ### Getting the User OCID 47 | 48 | To get the user OCID, follow these steps: 49 | 50 | 1. Log in to the OCI console. 51 | 2. From the OCI menu, select **Identity** > **Users**. 52 | 3. Click on the user you want to use with OCI Logging Grafana Data Source. 53 | 4. The user OCID is listed in the **User Details** section. 54 | 55 | ![OCI User](images/oci_user.png) 56 | 57 | For details and reference, see: [Where to Get the Tenancy's OCID and User's OCID](https://docs.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm#five). 58 | Please make note of the user OCID as you'll need it later to configure your OCI Logging Grafana Data Source. 59 | 60 | ### Getting the Private API Key and Fingerprint 61 | 62 | To get the private key, follow these steps: 63 | 64 | 1. Log in to your **OCI tenancy** and click on your username in the top right corner. 65 | 2. Go to **Resources** and **API Keys** and click on **Add API Key**. 66 | 3. Choose if you want to generate a new API key or use your own: 67 | - Select **Generate API Key Pair** if you want to generate a new API key. Click then on **Download Private Key** and **Download Public Key** to get your newly generated key 68 | - Select **Public Key File** or **Paste Public Key** in case you want to paste your public key: select **Paste Public Key** in the **Add API Key** dialog and copy and paste the key contents into the field, then click **Add**. 69 | 70 | 71 | ![OCI API Key](images/oci_apikey.png) 72 | 73 | 4. Once the key is added take note of the API key fingerprint listed in the **Fingerprint** column. 74 | 75 | ![OCI Fingerprint](images/oci_fingerprint.png) 76 | 77 | 78 | For details on how to create and configure keys see [How to Generate an API Signing Key](https://docs.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm#two) and [How to Upload the Public Key](https://docs.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm#three). 79 | Make note of the private key file location and API key fingerprint as you'll need it later to configure your OCI Logging Grafana Data Source. 80 | 81 | ## Configure OCI Identity Policies 82 | 83 | In the OCI console under **Identity > Groups** click **Create Group** and create a new group called **grafana**. Add the user configured in the OCI CLI to the newly-created group. 84 | 85 | ![OCIConsole-GroupList-Screenshot](images/OCIConsole-GroupList-Screenshot.png) 86 | 87 | Under the **Policy** tab click **Create Policy** and create policies allowing the group to read tenancy log objects and content. Add the following policy statements: 88 | 89 | - `allow group grafana to read log-groups in tenancy` 90 | - `allow group grafana to read log-content in tenancy` 91 | - `allow group grafana to read compartments in tenancy` 92 | - `allow group grafana to read audit-events in tenancy` 93 | 94 | ![OCIConsole-GroupLogsPolicyCreate-Screenshot](images/OCIConsole-GroupLogsPolicyCreate-Screenshot.png) 95 | 96 | The first two policies can also be limited to specific compartments in your tenancy by adding additional qualifiers to the policy statements. 97 | 98 | ## Install Grafana and the OCI Logging Plugin for Grafana Cloud 99 | 100 | To [install OCI Logging Plugin](https://grafana.com/grafana/plugins/oci-Logging-datasource/) on Grafana Cloud you need a valid [Grafana Cloud Account](https://grafana.com/products/cloud/). 101 | 102 | Log in to your Grafana Cloud Account and go to the **Administration** section: 103 | ![Administration](images/grafanacloud-administration.png) 104 | 105 | Select **Plugins** and search for **oracle**: 106 | ![Plugins](images/grafanacloud-plugins.png) 107 | 108 | Click on **Oracle Cloud Infrastructure Logging**. You will see the installation option for the plugin. Choose **install via grafana.con**: 109 | ![Install](images/grafanacloud-installlogs.png) 110 | 111 | You will be forwarded to the grafana.com website where you can proceed with the one-click installation. Make sure you will choose the correct Grafana Cloud account (in this example the account is named **Oracle** yours will be different) and follow the instruction on this web page to complete the plugin installation: 112 | ![One-click](images/grafanacloud-oneclick.png) 113 | 114 | 115 | ## Configure Grafana 116 | 117 | ### Configure Plugin in Single Tenancy Mode 118 | If you selected **single** as **Tenancy mode** then fill in the following credentials: 119 | 120 | * `Profile Name` - A user-defined name for this profile. In **single** mode this is automatically set to **DEFAULT** and cannot be modified. 121 | * `Region` - An OCI region. To get the value, see [**Getting Region Configuration value**](#getting-the-region). 122 | * `User OCID` - OCID of the user calling the API. To get the value, see [**Getting User OCID Configuration value**](#getting-the-user-OCID).* 123 | * `Tenancy OCID` - OCID of your tenancy. To get the value, see [**Getting Tenancy OCID Configuration value**](#getting-the-tenancy-OCID). 124 | * `Fingerprint` - Fingerprint for the key pair being used. To get the value, see [**Getting Fingerprint Configuration value**](#getting-the-private-api-key-and-fingerprint). 125 | * `Private Key` - The contents of the private key file. To get the value, see [**Getting Private Key Configuration value**](#getting-the-private-api-key-and-fingerprint). 126 | 127 | The configured data source will look like the following: 128 | 129 | ![Datasource Filled](images/logs_single_filled.png) 130 | 131 | Click **Save & Test** to return to the home dashboard. 132 | 133 | 134 | ### Configure Plugin in Multi-Tenancy Mode 135 | If you selected **multi** as **Tenancy mode** then fill in the following credentials for **each Tenancy you want to configure (up to 5 additional tenancies)**: 136 | 137 | * `Profile Name` - A user-defined name for this profile. The first Tenancy is automatically set to **DEFAULT** and cannot be modified. You need to specify a custom and unique Profile name for each of the additional tenancies. 138 | * `Region` - An OCI region. To get the value, see [**Getting Region Configuration value**](#getting-the-region). 139 | * `User OCID` - OCID of the user calling the API. To get the value, see [**Getting User OCID Configuration value**](#getting-the-user-OCID). 140 | * `Tenancy OCID` - OCID of your tenancy. To get the value, see [**Getting Tenancy OCID Configuration value**](#getting-the-tenancy-OCID). 141 | * `Fingerprint` - Fingerprint for the key pair being used. To get the value, see [**Getting Fingerprint Configuration value**](#getting-the-private-api-key-and-fingerprint). 142 | * `Private Key` - The contents of the private key file. To get the value, see [**Getting Private Key Configuration value**](#getting-the-private-api-key-and-fingerprint). 143 | 144 | By default, if you selected **multi** as **Tenancy mode** you can configure one DEFAULT tenancy with an additional one. You may add others tenancy **(up to 5 additional tenancies)** using the **Add another Tenancy** checkbox. 145 | 146 | The configured data source will look like the following: 147 | 148 | ![Datasource Filled](images/logs_multi_filled.png) 149 | 150 | Click **Save & Test** to return to the home dashboard. 151 | 152 | After the initial configuration, you can modify the datasource by adding a new tenancy by clicking on the **Add another Tenancy** checkbox and filling in the additional credentials. You can also disable a configured Tenancy leaving empty the **Profile Name** as in this screenshot: 153 | 154 | ![Tenancy Disabled](images/multi_disable.png) 155 | 156 | 157 | 158 | On the Oracle Cloud Infrastructure Logs data source configuration page, fill in your **Tenancy OCID**, **Default Region**, and **Authentication Provider**. Your **Default region** is the same as your home region listed on the **Tenancy Details** page. For **Authentication Provider** choose **OCI Instance**. 159 | 160 | Click **Save & Test** to test the configuration of the Logs data source. Click the Dashboard icon in the left-hand navigation menu to return to the home dashboard. 161 | 162 | ## Next Steps 163 | 164 | Check out how to use the newly installed and configured plugin in our [Using Grafana with Oracle Cloud Infrastructure Data Source](using.md) walkthrough. 165 | 166 | -------------------------------------------------------------------------------- /docs/images/Grafana-AddDataSource-Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/Grafana-AddDataSource-Screenshot.png -------------------------------------------------------------------------------- /docs/images/Grafana-ChangeDefaultAdminPassword-Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/Grafana-ChangeDefaultAdminPassword-Screenshot.png -------------------------------------------------------------------------------- /docs/images/Grafana-ConfigurationPluginsMenu-Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/Grafana-ConfigurationPluginsMenu-Screenshot.png -------------------------------------------------------------------------------- /docs/images/Grafana-ConfigurationPluginsSearch-Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/Grafana-ConfigurationPluginsSearch-Screenshot.png -------------------------------------------------------------------------------- /docs/images/Grafana-ConfigurationPluginsWindow-Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/Grafana-ConfigurationPluginsWindow-Screenshot.png -------------------------------------------------------------------------------- /docs/images/Grafana-CreateDashboardMenu-Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/Grafana-CreateDashboardMenu-Screenshot.png -------------------------------------------------------------------------------- /docs/images/Grafana-CreateDashboardWindow-Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/Grafana-CreateDashboardWindow-Screenshot.png -------------------------------------------------------------------------------- /docs/images/Grafana-DataSourceSearch-Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/Grafana-DataSourceSearch-Screenshot.png -------------------------------------------------------------------------------- /docs/images/Grafana-NewPanelEditor-Apply-Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/Grafana-NewPanelEditor-Apply-Screenshot.png -------------------------------------------------------------------------------- /docs/images/Grafana-NewPanelEditor-DataSource-Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/Grafana-NewPanelEditor-DataSource-Screenshot.png -------------------------------------------------------------------------------- /docs/images/Grafana-NewPanelEditor-PanelTitle-Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/Grafana-NewPanelEditor-PanelTitle-Screenshot.png -------------------------------------------------------------------------------- /docs/images/Grafana-NewPanelEditor-PanelType-Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/Grafana-NewPanelEditor-PanelType-Screenshot.png -------------------------------------------------------------------------------- /docs/images/Grafana-NewPanelEditor-QueryBox-Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/Grafana-NewPanelEditor-QueryBox-Screenshot.png -------------------------------------------------------------------------------- /docs/images/Grafana-NewPanelEditor-Region-Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/Grafana-NewPanelEditor-Region-Screenshot.png -------------------------------------------------------------------------------- /docs/images/Grafana-NewPanelEditor-TablePanelType-Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/Grafana-NewPanelEditor-TablePanelType-Screenshot.png -------------------------------------------------------------------------------- /docs/images/Grafana-OCILogsPluginConfigWindow-Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/Grafana-OCILogsPluginConfigWindow-Screenshot.png -------------------------------------------------------------------------------- /docs/images/Grafana-OCILogsPluginInstallWindow-Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/Grafana-OCILogsPluginInstallWindow-Screenshot.png -------------------------------------------------------------------------------- /docs/images/Grafana-OCILogsPluginInstalled-Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/Grafana-OCILogsPluginInstalled-Screenshot.png -------------------------------------------------------------------------------- /docs/images/Grafana-SelectOCILogsDataSource-Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/Grafana-SelectOCILogsDataSource-Screenshot.png -------------------------------------------------------------------------------- /docs/images/Grafana-TablePanel-EndResult-Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/Grafana-TablePanel-EndResult-Screenshot.png -------------------------------------------------------------------------------- /docs/images/Grafana-TablePanel-ExtractFieldsFormat-Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/Grafana-TablePanel-ExtractFieldsFormat-Screenshot.png -------------------------------------------------------------------------------- /docs/images/Grafana-TablePanel-ExtractFieldsResult-Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/Grafana-TablePanel-ExtractFieldsResult-Screenshot.png -------------------------------------------------------------------------------- /docs/images/Grafana-TablePanel-ExtractFieldsSource-Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/Grafana-TablePanel-ExtractFieldsSource-Screenshot.png -------------------------------------------------------------------------------- /docs/images/Grafana-TablePanel-Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/Grafana-TablePanel-Screenshot.png -------------------------------------------------------------------------------- /docs/images/Grafana-TablePanel-Xform-Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/Grafana-TablePanel-Xform-Screenshot.png -------------------------------------------------------------------------------- /docs/images/Grafana-TablePanel-XformSelection-Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/Grafana-TablePanel-XformSelection-Screenshot.png -------------------------------------------------------------------------------- /docs/images/Grafana-TemplateVars-BackToVarsScreen-Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/Grafana-TemplateVars-BackToVarsScreen-Screenshot.png -------------------------------------------------------------------------------- /docs/images/Grafana-TemplateVars-DashboardSettingsIcon-Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/Grafana-TemplateVars-DashboardSettingsIcon-Screenshot.png -------------------------------------------------------------------------------- /docs/images/Grafana-TemplateVars-DashboardSettingsScreen-Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/Grafana-TemplateVars-DashboardSettingsScreen-Screenshot.png -------------------------------------------------------------------------------- /docs/images/Grafana-TemplateVars-ExampleDropdown-Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/Grafana-TemplateVars-ExampleDropdown-Screenshot.png -------------------------------------------------------------------------------- /docs/images/Grafana-TemplateVars-IntervalVarConfig-Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/Grafana-TemplateVars-IntervalVarConfig-Screenshot.png -------------------------------------------------------------------------------- /docs/images/Grafana-TemplateVars-OfficialVars-Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/Grafana-TemplateVars-OfficialVars-Screenshot.png -------------------------------------------------------------------------------- /docs/images/Grafana-TemplateVars-PanelEditor-Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/Grafana-TemplateVars-PanelEditor-Screenshot.png -------------------------------------------------------------------------------- /docs/images/Grafana-TemplateVars-PanelEditorWithVars-Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/Grafana-TemplateVars-PanelEditorWithVars-Screenshot.png -------------------------------------------------------------------------------- /docs/images/Grafana-TemplateVars-Regions-Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/Grafana-TemplateVars-Regions-Screenshot.png -------------------------------------------------------------------------------- /docs/images/Grafana-TemplateVars-SelectionOptions-Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/Grafana-TemplateVars-SelectionOptions-Screenshot.png -------------------------------------------------------------------------------- /docs/images/Grafana-TemplateVars-VariablesScreen-NewVar-Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/Grafana-TemplateVars-VariablesScreen-NewVar-Screenshot.png -------------------------------------------------------------------------------- /docs/images/Grafana-TemplateVars-VariablesScreen-Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/Grafana-TemplateVars-VariablesScreen-Screenshot.png -------------------------------------------------------------------------------- /docs/images/Grafana-TimeSeries-AliasesExample1-Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/Grafana-TimeSeries-AliasesExample1-Screenshot.png -------------------------------------------------------------------------------- /docs/images/Grafana-TimeSeries-CustomQueryOptionsExample-Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/Grafana-TimeSeries-CustomQueryOptionsExample-Screenshot.png -------------------------------------------------------------------------------- /docs/images/Grafana-TimeSeries-ExampleGraph-Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/Grafana-TimeSeries-ExampleGraph-Screenshot.png -------------------------------------------------------------------------------- /docs/images/Grafana-TimeSeries-GroupByExample1-Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/Grafana-TimeSeries-GroupByExample1-Screenshot.png -------------------------------------------------------------------------------- /docs/images/Grafana-TimeSeries-GroupByExample2-Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/Grafana-TimeSeries-GroupByExample2-Screenshot.png -------------------------------------------------------------------------------- /docs/images/Grafana-TimeSeries-PanelOptions-Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/Grafana-TimeSeries-PanelOptions-Screenshot.png -------------------------------------------------------------------------------- /docs/images/Grafana-TimeSeries-PluginIntervalExample-Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/Grafana-TimeSeries-PluginIntervalExample-Screenshot.png -------------------------------------------------------------------------------- /docs/images/Grafana-TimeSeries-QueryOptions-Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/Grafana-TimeSeries-QueryOptions-Screenshot.png -------------------------------------------------------------------------------- /docs/images/Grafana-TimeSeries-rounddownExample-Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/Grafana-TimeSeries-rounddownExample-Screenshot.png -------------------------------------------------------------------------------- /docs/images/GrafanaHomePage-Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/GrafanaHomePage-Screenshot.png -------------------------------------------------------------------------------- /docs/images/GrafanaLogin-Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/GrafanaLogin-Screenshot.png -------------------------------------------------------------------------------- /docs/images/OCIConsole-DynamicGroupList-Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/OCIConsole-DynamicGroupList-Screenshot.png -------------------------------------------------------------------------------- /docs/images/OCIConsole-GroupList-Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/OCIConsole-GroupList-Screenshot.png -------------------------------------------------------------------------------- /docs/images/OCIConsole-GroupLogsPolicyCreate-Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/OCIConsole-GroupLogsPolicyCreate-Screenshot.png -------------------------------------------------------------------------------- /docs/images/OCIConsole-PoliciesList-Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/OCIConsole-PoliciesList-Screenshot.png -------------------------------------------------------------------------------- /docs/images/Screen Shot 2018-12-17 at 3.58.23 PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/Screen Shot 2018-12-17 at 3.58.23 PM.png -------------------------------------------------------------------------------- /docs/images/Screen Shot 2018-12-17 at 3.59.38 PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/Screen Shot 2018-12-17 at 3.59.38 PM.png -------------------------------------------------------------------------------- /docs/images/Screen Shot 2018-12-17 at 4.01.34 PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/Screen Shot 2018-12-17 at 4.01.34 PM.png -------------------------------------------------------------------------------- /docs/images/Screen Shot 2018-12-17 at 4.01.47 PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/Screen Shot 2018-12-17 at 4.01.47 PM.png -------------------------------------------------------------------------------- /docs/images/Screen Shot 2018-12-17 at 4.04.42 PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/Screen Shot 2018-12-17 at 4.04.42 PM.png -------------------------------------------------------------------------------- /docs/images/create-alert-expression.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/create-alert-expression.png -------------------------------------------------------------------------------- /docs/images/custom_var.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/custom_var.png -------------------------------------------------------------------------------- /docs/images/datasource_single_empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/datasource_single_empty.png -------------------------------------------------------------------------------- /docs/images/datasource_single_full.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/datasource_single_full.png -------------------------------------------------------------------------------- /docs/images/dgGroup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/dgGroup.png -------------------------------------------------------------------------------- /docs/images/dgPolicy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/dgPolicy.png -------------------------------------------------------------------------------- /docs/images/grafanacloud-adddatasource.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/grafanacloud-adddatasource.png -------------------------------------------------------------------------------- /docs/images/grafanacloud-administration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/grafanacloud-administration.png -------------------------------------------------------------------------------- /docs/images/grafanacloud-installlogs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/grafanacloud-installlogs.png -------------------------------------------------------------------------------- /docs/images/grafanacloud-login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/grafanacloud-login.png -------------------------------------------------------------------------------- /docs/images/grafanacloud-oneclick.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/grafanacloud-oneclick.png -------------------------------------------------------------------------------- /docs/images/grafanacloud-plugins.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/grafanacloud-plugins.png -------------------------------------------------------------------------------- /docs/images/grafanacloud-searchdatasource.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/grafanacloud-searchdatasource.png -------------------------------------------------------------------------------- /docs/images/instance_principals.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/instance_principals.png -------------------------------------------------------------------------------- /docs/images/log_var_custom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/log_var_custom.png -------------------------------------------------------------------------------- /docs/images/logs_multi_filled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/logs_multi_filled.png -------------------------------------------------------------------------------- /docs/images/logs_single_filled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/logs_single_filled.png -------------------------------------------------------------------------------- /docs/images/multi_disable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/multi_disable.png -------------------------------------------------------------------------------- /docs/images/multi_regions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/multi_regions.png -------------------------------------------------------------------------------- /docs/images/multi_templating_tenancies.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/multi_templating_tenancies.png -------------------------------------------------------------------------------- /docs/images/multi_templating_vars.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/multi_templating_vars.png -------------------------------------------------------------------------------- /docs/images/multi_tenancy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/multi_tenancy.png -------------------------------------------------------------------------------- /docs/images/oci_administration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/oci_administration.png -------------------------------------------------------------------------------- /docs/images/oci_apikey.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/oci_apikey.png -------------------------------------------------------------------------------- /docs/images/oci_fingerprint.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/oci_fingerprint.png -------------------------------------------------------------------------------- /docs/images/oci_tenancy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/oci_tenancy.png -------------------------------------------------------------------------------- /docs/images/oci_user.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/oci_user.png -------------------------------------------------------------------------------- /docs/images/usrGp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/usrGp.png -------------------------------------------------------------------------------- /docs/images/usrPolicy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/oci-grafana-logs/1164483d0a07304c35ce0a9eead64752eaa20c55/docs/images/usrPolicy.png -------------------------------------------------------------------------------- /docs/kubernetes.md: -------------------------------------------------------------------------------- 1 | # Oracle Kubernetes Engine Installation - Oracle Cloud Infrastructure Data Source for Grafana 2 | 3 | ## Pre-requisites: 4 | 5 | * [Oracle Container Engine for Kubernetes (OKE)](http://www.oracle.com/webfolder/technetwork/tutorials/obe/oci/oke-full/index.html) 6 | * [Kubectl 1.7.4](https://kubernetes.io/docs/tasks/tools/install-kubectl/) 7 | * [Helm](https://github.com/kubernetes/helm#install) 8 | 9 | ## Background 10 | 11 | Grafana is a popular technology that makes it easy to visualize logs and metrics. The [Oracle Cloud Infrastructure Logs Data Source for Grafana](https://grafana.com/grafana/plugins/oci-logs-datasource/) is used to extend Grafana by adding OCI Logging as a data source. The plugin enables you to visualize log records (service, audit, and custom) and metrics derived from log records stored in the OCI Logging service. 12 | 13 | This walkthrough is intended for use by people who would like to deploy Grafana and the OCI Logs Data Source for Grafana in a Kubernetes environment. 14 | 15 | Make sure you have access to the [Logging Service](https://docs.oracle.com/en-us/iaas/Content/Logging/Concepts/loggingoverview.htm) and that the logs you want to observe and analyze are being collected in your tenancy. See the OCI Logging documentation for information on how to collect or access: 16 | * [Logs from your compute instances](https://docs.oracle.com/en-us/iaas/Content/Logging/Concepts/agent_management.htm) 17 | * [Custom logs from your application/services](https://docs.oracle.com/en-us/iaas/Content/Logging/Concepts/custom_logs.htm) 18 | * [OCI service logs](https://docs.oracle.com/en-us/iaas/Content/Logging/Concepts/service_logs.htm). 19 | 20 | ## Configuring the OCI Identity policies 21 | 22 | In order to use the the OCI Logging Data Source for Grafana on OKE, the first step is to create a [dynamic group](https://docs.cloud.oracle.com/iaas/Content/Identity/Tasks/managingdynamicgroups.htm) used to group virtual machine or bare metal compute instances as “principals” (similar to user groups). Create a dynamic group that corresponds to all of your OKE worker nodes: 23 | 24 | ![OCIConsole-DynamicGroupList-Screenshot](images/OCIConsole-DynamicGroupList-Screenshot.png) 25 | 26 | Next, create a [policy](https://docs.cloud.oracle.com/iaas/Content/Identity/Concepts/policygetstarted.htm), for example named “grafana_policy”, in the root compartment of your tenancy to permit instances in the dynamic group to make API calls against Oracle Cloud Infrastructure services. Add the following policy statements: 27 | 28 | * `allow dynamicgroup grafana to read log-groups in tenancy` 29 | * `allow dynamicgroup grafana to read log-content in tenancy` 30 | * `allow dynamicgroup grafana to read compartments in tenancy` 31 | * `allow dynamicgroup grafana to read audit-events in tenancy` 32 | 33 | ![OCIConsole-PoliciesList-Screenshot](images/OCIConsole-PoliciesList-Screenshot.png) 34 | 35 | The first two policies can also be limited to specific compartments in your tenancy by adding additional qualifiers to the policy statements. 36 | 37 | ## The Grafana Helm chart 38 | 39 | Next, we are going to install the stable Helm chart for Grafana. We will do this in two parts: First, update the stable repository by running: `helm repo update` 40 | 41 | Next, install the stable chart for Grafana. To do this run: `helm install --name grafana stable/grafana` 42 | 43 | We can now make a change to the deployment that was created for Grafana by running `kubectl edit deployment grafana`, and adding an additional environment variable to the Grafana contianer which will download the plugin. After saving the deployment, the changes will be reflected with a new pod. 44 | 45 | ``` 46 | - name: GF_INSTALL_PLUGINS 47 | value: oci-logs-datasource 48 | ``` 49 | 50 | ## Accessing Grafana 51 | 52 | To see if everything is working correctly, access Grafana using Kubernetes port-forwarding. To do this run: `export POD_NAME=$(kubectl get pods --namespace default -l "app=grafana,release=grafana" -o jsonpath="{.items[0].metadata.name}")` 53 | 54 | Followed by: `kubectl --namespace default port-forward $POD_NAME 3000` 55 | 56 | You can obtain the password for the admin user by running: `kubectl get secret --namespace default grafana -o jsonpath="{.data.admin-password}" | base64 --decode ; echo` 57 | 58 | ## Configure Grafana 59 | 60 | The next step is to configure the plugin. Navigate to the Grafana homepage at `http://localhost:3000` 61 | 62 | ![GrafanaLogin-Screenshot](images/GrafanaLogin-Screenshot.png) 63 | 64 | Log in with the default username `admin` and the password you obtained from the kubectl command from the previous section. 65 | 66 | On the Home Dashboard click the gear icon on the left side of the page and then select **Data sources** from the Configuration menu. 67 | 68 | ![GrafanaHomePage-Screenshot](images/GrafanaHomePage-Screenshot.png) 69 | 70 | Click **Add data source**. 71 | 72 | ![Grafana-AddDataSource-Screenshot](images/Grafana-AddDataSource-Screenshot.png) 73 | 74 | In the search box at the top of the resulting page, enter 'oracle'. 75 | 76 | ![Grafana-DataSourceSearch-Screenshot](images/Grafana-DataSourceSearch-Screenshot.png) 77 | 78 | Click the **Oracle Cloud Infrastructure Logs** box to select it as your data source type. 79 | 80 | ![Grafana-SelectOCILogsDataSource-Screenshot](images/Grafana-SelectOCILogsDataSource-Screenshot.png) 81 | 82 | On the Oracle Cloud Infrastructure Logs data source configuration page, fill in your **Tenancy OCID**, **Default Region**, and **Authentication Provider**. Your **Default region** is the same as your home region listed in the **Tenancy Details** page. For **Authentication Provider** choose **OCI Instance**. 83 | 84 | Click **Save & Test** to test the configuration of the Logs data source. Click the Dashboard icon in the left hand navigation menu to return to the home dashboard. 85 | 86 | ![Grafana-OCILogsPluginConfigWindow-Screenshot](images/Grafana-OCILogsPluginConfigWindow-Screenshot.png) 87 | 88 | ## Next Steps 89 | 90 | Check out how to use the newly installed and configured plugin in our [Using Grafana with Oracle Cloud Infrastructure Data Source](using.md) walkthrough. 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /docs/linux.md: -------------------------------------------------------------------------------- 1 | # Local Installation (Linux) - Oracle Cloud Infrastructure Data Source for Grafana 2 | 3 | ## Background 4 | 5 | Grafana is a popular technology that makes it easy to visualize logs and metrics. The [Oracle Cloud Infrastructure Logs Data Source for Grafana](https://grafana.com/grafana/plugins/oci-logs-datasource/) is used to extend Grafana by adding OCI Logging as a data source. The plugin enables you to visualize log records (service, audit, and custom) and metrics derived from log records stored in the OCI Logging service. 6 | 7 | This walkthrough is intended for use by people who would like to deploy Grafana and the OCI Logs Data Source for Grafana on a local Linux server. 8 | 9 | Make sure you have access to the [Logging Service](https://docs.oracle.com/en-us/iaas/Content/Logging/Concepts/loggingoverview.htm) and that the logs you want to observe and analyze are being collected in your tenancy. See the OCI Logging documentation for information on how to collect or access: 10 | * [Logs from your compute instances](https://docs.oracle.com/en-us/iaas/Content/Logging/Concepts/agent_management.htm) 11 | * [Custom logs from your application/services](https://docs.oracle.com/en-us/iaas/Content/Logging/Concepts/custom_logs.htm) 12 | * [OCI service logs](https://docs.oracle.com/en-us/iaas/Content/Logging/Concepts/service_logs.htm). 13 | 14 | ## Getting OCI Configuration values 15 | 16 | To configure OCI Logging Grafana Data Source, you'll need to get the necessary provider and resource settings. Please note that Migrating from version 2.x.x to 3.x.x will require migrating the existing data source configuration: using version 3.x.x of the plugin with the data source configuration of version 2.x.x is **not possible**. In case you are migrating from previous version 2.x.x of the OCI Logging Grafana Plugin, you can refer to the [**Migration Instructions for Grafana OCI Logging Data Source Settings (User Principals and Single Tenancy mode only)**](migration.md). If you are configuring the plugin to work in Multitenancy Mode, you will need to repeat the following steps for each of the Tenancies you want to configure with the plugin (up to 5 additional Tenancies are supported). 17 | 18 | ### Getting the Region 19 | 20 | To get the region for your OCI cloud, follow these steps: 21 | 22 | 1. Log in to the OCI console. 23 | 2. From the OCI menu, select the **Region** dropdown in the top right corner of the page. 24 | 3. The region is listed next to **Home**. 25 | 26 | For details and reference, see: [Regions and Availability Domains](https://docs.oracle.com/en-us/iaas/Content/General/Concepts/regions.htm#top) 27 | Please make note of the region as you'll need it later to configure your OCI Logging Grafana Data Source. 28 | 29 | ### Getting the Tenancy OCID 30 | 31 | To get the tenancy OCID, follow these steps: 32 | 33 | 1. Log in to the OCI console. 34 | 2. From the OCI menu, click on your profile icon on the top right: 35 | 36 | ![OCI Administration](images/oci_administration.png) 37 | 38 | 3. Click on Tenancy 39 | 4. The tenancy OCID is listed in the **Tenancy Information** section. 40 | 41 | ![OCI Tenancy](images/oci_tenancy.png) 42 | 43 | For details and reference, see: [Where to Get the Tenancy's OCID and User's OCID](https://docs.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm#five) 44 | Please make note of the tenancy OCID as you'll need it later to configure your OCI Logging Grafana Data Source. 45 | 46 | ### Getting the User OCID 47 | 48 | To get the user OCID, follow these steps: 49 | 50 | 1. Log in to the OCI console. 51 | 2. From the OCI menu, select **Identity** > **Users**. 52 | 3. Click on the user you want to use with OCI Logging Grafana Data Source. 53 | 4. The user OCID is listed in the **User Details** section. 54 | 55 | ![OCI User](images/oci_user.png) 56 | 57 | For details and reference, see: [Where to Get the Tenancy's OCID and User's OCID](https://docs.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm#five). 58 | Please make note of the user OCID as you'll need it later to configure your OCI Logging Grafana Data Source. 59 | 60 | ### Getting the Private API Key and Fingerprint 61 | 62 | To get the private key, follow these steps: 63 | 64 | 1. Log in to your **OCI tenancy** and click on your username in the top right corner. 65 | 2. Go to **Resources** and **API Keys** and click on **Add API Key**. 66 | 3. Choose if you want to generate a new API key or use your own: 67 | - Select **Generate API Key Pair** if you want to generate a new API key. Click then on **Download Private Key** and **Download Public Key** to get your newly generated key 68 | - Select **Public Key File** or **Paste Public Key** in case you want to paste your public key: select **Paste Public Key** in the **Add API Key** dialog and copy and paste the key contents into the field, then click **Add**. 69 | 70 | 71 | ![OCI API Key](images/oci_apikey.png) 72 | 73 | 4. Once the key is added take note of the API key fingerprint listed in the **Fingerprint** column. 74 | 75 | ![OCI Fingerprint](images/oci_fingerprint.png) 76 | 77 | 78 | For details on how to create and configure keys see [How to Generate an API Signing Key](https://docs.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm#two) and [How to Upload the Public Key](https://docs.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm#three). 79 | Make note of the private key file location and API key fingerprint as you'll need it later to configure your OCI Logging Grafana Data Source. 80 | 81 | ## Configure OCI Identity Policies 82 | 83 | In the OCI console under **Identity > Groups** click **Create Group** and create a new group called **grafana**. Add the user configured in the OCI CLI to the newly-created group. 84 | 85 | ![OCIConsole-GroupList-Screenshot](images/OCIConsole-GroupList-Screenshot.png) 86 | 87 | Under the **Policy** tab click **Create Policy** and create policies allowing the group to read tenancy log objects and content. Add the following policy statements: 88 | 89 | - `allow group grafana to read log-groups in tenancy` 90 | - `allow group grafana to read log-content in tenancy` 91 | - `allow group grafana to read compartments in tenancy` 92 | - `allow group grafana to read audit-events in tenancy` 93 | 94 | ![OCIConsole-GroupLogsPolicyCreate-Screenshot](images/OCIConsole-GroupLogsPolicyCreate-Screenshot.png) 95 | 96 | The first two policies can also be limited to specific compartments in your tenancy by adding additional qualifiers to the policy statements. 97 | 98 | ## Install Grafana and the OCI Logs Data Source for Grafana Plugin 99 | 100 | To [install the OCI Logs data source](https://grafana.com/plugins/oci-logs-datasource/installation) make sure you are running [Grafana 8.0](https://grafana.com/get) or later. Use the [grafana-cli tool](http://docs.grafana.org/plugins/installation/) to install the Oracle Cloud Infrastructure Logs Data Source for Grafana from the command line: 101 | 102 | ``` 103 | grafana-cli plugins install oci-logs-datasource 104 | ``` 105 | 106 | The plugin will be installed into your grafana plugins directory, which by default is located at /var/lib/grafana/plugins. [Here is more information on the CLI tool](http://docs.grafana.org/plugins/installation/). 107 | 108 | ### Manual installation 109 | Alternatively, you can manually download the .tar file and unpack it into your /grafana/plugins directory. To do so, change to the Grafana plugins directory: `cd /usr/local/var/lib/grafana/plugins`. Download the OCI Grafana Plugin: wget `https://github.com/oracle/oci-grafana-logs/releases/latest/download/plugin.tar`. Create a directory and install the plugin: `mkdir oci && tar -C oci -xvf plugin.tar` and then remove the tarball: `rm plugin.tar`. 110 | 111 | > **Additional step for Grafana 8**. Open the grafana configuration *grafana.ini* file and add the `allow_loading_unsigned_plugins = "oci-logs-datasource"` in the *plugins* section. 112 | 113 | *Example* 114 | ``` 115 | [plugins] 116 | ;enable_alpha = false 117 | ;app_tls_skip_verify_insecure = false 118 | allow_loading_unsigned_plugins = "oci-logs-datasource" 119 | ``` 120 | 121 | To start the Grafana server, run: `sudo systemctl start grafana-server`. 122 | 123 | 124 | ## Configure Grafana 125 | 126 | You can use a manual configuration or a programatic configuration. 127 | In case you want to use the datasource.yaml based plugin configuration you can refers to this document: [Data source configuration using yaml file](datasource_configuration.md) 128 | For manual approach continue to read this document. 129 | 130 | The next step is to configure the plugin. Navigate to the Grafana homepage at `http://localhost:3000` 131 | 132 | ![GrafanaLogin-Screenshot](images/GrafanaLogin-Screenshot.png) 133 | 134 | Log in with the default username `admin` and the password `admin`. You will be prompted to change your password. Click **Skip** or **Save** to continue. 135 | 136 | ![Grafana-ChangeDefaultAdminPassword-Screenshot](images/Grafana-ChangeDefaultAdminPassword-Screenshot.png) 137 | 138 | On the Home Dashboard click the gear icon on the left side of the page and then select **Data sources** from the Configuration menu. 139 | 140 | ![GrafanaHomePage-Screenshot](images/GrafanaHomePage-Screenshot.png) 141 | 142 | Click **Add data source**. 143 | 144 | ![Grafana-AddDataSource-Screenshot](images/Grafana-AddDataSource-Screenshot.png) 145 | 146 | In the search box at the top of the resulting page, enter 'oracle'. 147 | 148 | ![Grafana-DataSourceSearch-Screenshot](images/Grafana-DataSourceSearch-Screenshot.png) 149 | 150 | Click the **Oracle Cloud Infrastructure Logs** box to select it as your data source type. 151 | 152 | ![Grafana-SelectOCILogsDataSource-Screenshot](images/Grafana-SelectOCILogsDataSource-Screenshot.png) 153 | 154 | 155 | This Configuration screen will appear: 156 | 157 | ![Datasource Empty](images/datasource_single_empty.png) 158 | 159 | For **Authentication Provider** choose **local** and then choose between **single** or **multitenancy** as **Tenancy mode**. 160 | You can then choose between two different modes as **Tenancy mode**: 161 | 162 | * **single**: to use a single specific Tenancy 163 | * **multitenancy**: to use multiple tenancies 164 | 165 | ### Configure Plugin in Single Tenancy Mode 166 | If you selected **single** as **Tenancy mode** then fill in the following credentials: 167 | 168 | * `Profile Name` - A user-defined name for this profile. In **single** mode this is automatically set to **DEFAULT** and cannot be modified. 169 | * `Region` - An OCI region. To get the value, see [**Getting Region Configuration value**](#getting-the-region). 170 | * `User OCID` - OCID of the user calling the API. To get the value, see [**Getting User OCID Configuration value**](#getting-the-user-OCID).* 171 | * `Tenancy OCID` - OCID of your tenancy. To get the value, see [**Getting Tenancy OCID Configuration value**](#getting-the-tenancy-OCID). 172 | * `Fingerprint` - Fingerprint for the key pair being used. To get the value, see [**Getting Fingerprint Configuration value**](#getting-the-private-api-key-and-fingerprint). 173 | * `Private Key` - The contents of the private key file. To get the value, see [**Getting Private Key Configuration value**](#getting-the-private-api-key-and-fingerprint). 174 | 175 | The configured data source will look like the following: 176 | 177 | ![Datasource Filled](images/datasource_single_full.png) 178 | 179 | Click **Save & Test** to return to the home dashboard. 180 | 181 | 182 | ### Configure Plugin in Multi-Tenancy Mode 183 | If you selected **multi** as **Tenancy mode** then fill in the following credentials for **each Tenancy you want to configure (up to 5 additional tenancies)**: 184 | 185 | * `Profile Name` - A user-defined name for this profile. The first Tenancy is automatically set to **DEFAULT** and cannot be modified. You need to specify a custom and unique Profile name for each of the additional tenancies. 186 | * `Region` - An OCI region. To get the value, see [**Getting Region Configuration value**](#getting-the-region). 187 | * `User OCID` - OCID of the user calling the API. To get the value, see [**Getting User OCID Configuration value**](#getting-the-user-OCID). 188 | * `Tenancy OCID` - OCID of your tenancy. To get the value, see [**Getting Tenancy OCID Configuration value**](#getting-the-tenancy-OCID). 189 | * `Fingerprint` - Fingerprint for the key pair being used. To get the value, see [**Getting Fingerprint Configuration value**](#getting-the-private-api-key-and-fingerprint). 190 | * `Private Key` - The contents of the private key file. To get the value, see [**Getting Private Key Configuration value**](#getting-the-private-api-key-and-fingerprint). 191 | 192 | By default, if you selected **multi** as **Tenancy mode** you can configure one DEFAULT tenancy with an additional one. You may add others tenancy **(up to 5 additional tenancies)** using the **Add another Tenancy** checkbox. 193 | 194 | The configured data source will look like the following: 195 | 196 | ![Datasource Filled](images/logs_multi_filled.png) 197 | 198 | Click **Save & Test** to return to the home dashboard. 199 | 200 | After the initial configuration, you can modify the datasource by adding a new tenancy by clicking on the **Add another Tenancy** checkbox and filling in the additional credentials. You can also disable a configured Tenancy leaving empty the **Profile Name** as in this screenshot: 201 | 202 | ![Tenancy Disabled](images/multi_disable.png) 203 | 204 | 205 | 206 | On the Oracle Cloud Infrastructure Logs data source configuration page, fill in your **Tenancy OCID**, **Default Region**, and **Authentication Provider**. Your **Default region** is the same as your home region listed on the **Tenancy Details** page. For **Authentication Provider** choose **OCI Instance**. 207 | 208 | Click **Save & Test** to test the configuration of the Logs data source. Click the Dashboard icon in the left-hand navigation menu to return to the home dashboard. 209 | 210 | ## Next Steps 211 | 212 | Check out how to use the newly installed and configured plugin in our [Using Grafana with Oracle Cloud Infrastructure Data Source](using.md) walkthrough. 213 | 214 | -------------------------------------------------------------------------------- /docs/linuxoci.md: -------------------------------------------------------------------------------- 1 | # OCI Virtual Machine Installation - Oracle Cloud Infrastructure Data Source for Grafana 2 | 3 | ## Background 4 | 5 | Grafana is a popular technology that makes it easy to visualize logs and metrics. The [Oracle Cloud Infrastructure Logs Data Source for Grafana](https://grafana.com/grafana/plugins/oci-logs-datasource/) is used to extend Grafana by adding OCI Logging as a data source. The plugin enables you to visualize log records (service, audit, and custom) and metrics derived from log records stored in the OCI Logging service. 6 | 7 | This walkthrough is intended for use by people who would like to deploy Grafana and the OCI Logs Data Source for Grafana on a virtual machine in OCI. 8 | 9 | Make sure you have access to the [Logging Service](https://docs.oracle.com/en-us/iaas/Content/Logging/Concepts/loggingoverview.htm) and that the logs you want to observe and analyze are being collected in your tenancy. See the OCI Logging documentation for information on how to collect or access: 10 | * [Logs from your compute instances](https://docs.oracle.com/en-us/iaas/Content/Logging/Concepts/agent_management.htm) 11 | * [Custom logs from your application/services](https://docs.oracle.com/en-us/iaas/Content/Logging/Concepts/custom_logs.htm) 12 | * [OCI service logs](https://docs.oracle.com/en-us/iaas/Content/Logging/Concepts/service_logs.htm). 13 | 14 | ## Create the Grafana Environment in OCI 15 | 16 | Provision an Oracle Linux [virtual machine](https://docs.cloud.oracle.com/iaas/Content/Compute/Concepts/computeoverview.htm) in OCI connected to a [Virtual Cloud Network](https://docs.cloud.oracle.com/iaas/Content/Network/Tasks/managingVCNs.htm) with access to the public internet. If you do not already have access to a Virtual Cloud Network with access to the public internet you can navigate to **Virtual Cloud Networks** under **Networking** and click **Create Virtual Cloud Network**. Choosing the `CREATE VIRTUAL CLOUD NETWORK PLUS RELATED RESOURCES` option will result in a VCN with an Internet Routing Gateway and Route Tables configured for access to the public internet. Three subnets will be created: one in each availability domain in the region. 17 | 18 | After creating your VM, the next step is to create a [dynamic group](https://docs.cloud.oracle.com/iaas/Content/Identity/Tasks/managingdynamicgroups.htm) used to group virtual machine or bare metal compute instances as “principals” (similar to user groups). 19 | 20 | ![OCIConsole-DynamicGroupList-Screenshot](images/OCIConsole-DynamicGroupList-Screenshot.png) 21 | 22 | Next, create a [policy](https://docs.cloud.oracle.com/iaas/Content/Identity/Concepts/policygetstarted.htm), for example named “grafana_policy”, in the root compartment of your tenancy to permit instances in the dynamic group to make API calls against Oracle Cloud Infrastructure services. Add the following policy statements: 23 | 24 | * `allow dynamicgroup grafana to read log-groups in tenancy` 25 | * `allow dynamicgroup grafana to read log-content in tenancy` 26 | * `allow dynamicgroup grafana to read compartments in tenancy` 27 | * `allow dynamicgroup grafana to read audit-events in tenancy` 28 | 29 | ![OCIConsole-PoliciesList-Screenshot](images/OCIConsole-PoliciesList-Screenshot.png) 30 | 31 | The first two policies can also be limited to specific compartments in your tenancy by adding additional qualifiers to the policy statements. 32 | 33 | ## Install Grafana and the OCI Logs Data Source for Grafana Plugin 34 | 35 | To [install the OCI Logs data source](https://grafana.com/plugins/oci-logs-datasource/installation) make sure you are running [Grafana 8.0](https://grafana.com/get) or later. Use the [grafana-cli tool](http://docs.grafana.org/plugins/installation/) to install the Oracle Cloud Infrastructure Logs Data Source for Grafana from the command line: 36 | 37 | ``` 38 | grafana-cli plugins install oci-logs-datasource 39 | ``` 40 | 41 | The plugin will be installed into your Grafana plugins directory, which by default is located at /var/lib/grafana/plugins. [Here is more information on the CLI tool](http://docs.grafana.org/plugins/installation/). 42 | 43 | ### Manual installation 44 | Alternatively, you can manually download the .tar file and unpack it into your /grafana/plugins directory. To do so, change to the Grafana plugins directory: `cd /usr/local/var/lib/grafana/plugins`. Download the OCI Logs Grafana Plugin: wget `https://github.com/oracle/oci-grafana-logs/releases/latest/download/plugin.tar`. Create a directory and install the plugin: `mkdir oci && tar -C oci -xvf plugin.tar` and then remove the tarball: `rm plugin.tar`. 45 | 46 | > **Additional step for Grafana 8**. Open the grafana configuration *grafana.ini* file and add the `allow_loading_unsigned_plugins = "oci-logs-datasource"`in the *plugins* section. 47 | 48 | *Example* 49 | ``` 50 | [plugins] 51 | ;enable_alpha = false 52 | ;app_tls_skip_verify_insecure = false 53 | allow_loading_unsigned_plugins = "oci-logs-datasource" 54 | ``` 55 | 56 | To start the Grafana server, run: `sudo systemctl start grafana-server`. 57 | 58 | 59 | ## Configure Grafana 60 | 61 | You can use a manual configuration or a programatic configuration. 62 | In case you want to use the datasource.yaml based plugin configuration you can refers to this document: [Data source configuration using yaml file](datasource_configuration.md) 63 | For manual approach continue to read this document. 64 | 65 | The next step is to configure the plugin. To find the IP address of the newly-created instance, navigate to Compute > Instances > [Your Instance]. The Public IP address is listed under the Primary VNIC Information section. Connect to Grafana via port forward by running `ssh opc@[Instance Public IP] -L 3000:localhost:3000`. 66 | 67 | Navigate to the Grafana homepage at http://localhost:3000. 68 | 69 | ![GrafanaLogin-Screenshot](images/GrafanaLogin-Screenshot.png) 70 | 71 | Log in with the default username `admin` and the password `admin`. You will be prompted to change your password. Click **Skip** or **Save** to continue. 72 | 73 | ![Grafana-ChangeDefaultAdminPassword-Screenshot](images/Grafana-ChangeDefaultAdminPassword-Screenshot.png) 74 | 75 | On the Home Dashboard click the gear icon on the left side of the page and then select **Data sources** from the Configuration menu. 76 | 77 | ![GrafanaHomePage-Screenshot](images/GrafanaHomePage-Screenshot.png) 78 | 79 | Click **Add data source**. 80 | 81 | ![Grafana-AddDataSource-Screenshot](images/Grafana-AddDataSource-Screenshot.png) 82 | 83 | In the search box at the top of the resulting page, enter 'oracle'. 84 | 85 | ![Grafana-DataSourceSearch-Screenshot](images/Grafana-DataSourceSearch-Screenshot.png) 86 | 87 | Click the **Oracle Cloud Infrastructure Logs** box to select it as your data source type. 88 | 89 | ![Grafana-SelectOCILogsDataSource-Screenshot](images/Grafana-SelectOCILogsDataSource-Screenshot.png) 90 | 91 | On the Oracle Cloud Infrastructure Logs data source configuration page, fill in your **Tenancy OCID**, **Default Region**, and **Authentication Provider**. Your **Default region** is the same as your home region listed in the **Tenancy Details** page. For **Authentication Provider** choose **OCI Instance**. 92 | ![Instance Principals](images/instance_principals.png) 93 | 94 | Click **Save & Test** to return to the home dashboard. 95 | 96 | ![Grafana-OCILogsPluginConfigWindow-Screenshot](images/Grafana-OCILogsPluginConfigWindow-Screenshot.png) 97 | 98 | ## Next Steps 99 | 100 | Check out how to use the newly installed and configured plugin in our [Using Grafana with Oracle Cloud Infrastructure Data Source](using.md) walkthrough. 101 | -------------------------------------------------------------------------------- /docs/migration.md: -------------------------------------------------------------------------------- 1 | ## Migration Instructions for Grafana OCI Logging Data Source Settings (User Principals and Single Tenancy mode only) 2 | 3 | DO NOT USE this migration guide if your OCI Logging Data Source is configured to use the `Instance Principals` authentication method. This guide is intended for users who are using the `User Principal` authentication method! In case your Data Source is using the `Instance Principals` authentication method there is no need to migrate. 4 | 5 | This document describes the steps to migrate data from the `.oci/config` file to the Grafana data source settings for the following variables: 6 | 7 | * `user` 8 | * `fingerprint` 9 | * `tenancy` 10 | * `region` 11 | 12 | Additionally, we will copy the ID key stored in a file (whose path is stored in the `key_file` variable) into the Grafana data source settings. 13 | 14 | ### Prerequisites 15 | 16 | Before starting the migration process, please make sure you have the following: 17 | 18 | * Access to the Grafana instance where the data source settings will be updated. 19 | * The `.oci/config` file containing the variables to be migrated (`user`, `fingerprint`, `tenancy`, `region`) and the ID key (`key_file`). 20 | 21 | ### Steps 22 | 23 | 1. Log in to your Grafana instance and go to the data source settings page. 24 | 2. Locate the OCI Logging data source where you want to update the settings and click on the "Edit" button. Configuration parameters will look like the following: 25 | ![Datasource Empty](images/datasource_single_empty.png) 26 | 3. Choose `local` as `Environment` and `single` as `Tenancy Mode` 27 | 4. Fill in the following: 28 | * `Profile Name` - A user-defined name for this profile. In **single** mode this is automatically set to **DEFAULT** and cannot be modified. 29 | * `Region` - An OCI region. Update it with the content of variables `region` from the `.oci/config` file. 30 | * `User OCID` - OCID of the user calling the API. Update it with the content of variables `user` from the `.oci/config` file. 31 | * `Tenancy OCID` - OCID of your tenancy. Update it with the content of variables `tenancy` from the `.oci/config` from the `.oci/config` file. 32 | * `Fingerprint` - Fingerprint for the key pair being used. Update it with the content of variables `fingerprint` from the `.oci/config` file. 33 | * `Private Key` - The contents of the private key file. Update it with the content of the file stored at the path specified in the `key_file` variable in the `.oci/config` file. 34 | 5. Save the changes to the data source settings. Configuration parameters will look then like the following: 35 | ![Datasource Filled](images/datasource_single_full.png) 36 | 37 | 38 | ### Conclusion 39 | 40 | By following these steps, you should have successfully migrated the data from the `.oci/config` file to the Grafana OCI Logging data source settings (User Principals and Single Tenancy mode only) for the specified variables and the ID key. Please note that the process cannot be reverted, and rollback to the previous configuration with the config file is not possible. Also, once migrated to version 4.x.x of the plugin, moving back to version 3.x.x is not possible. 41 | -------------------------------------------------------------------------------- /docs/terraform.md: -------------------------------------------------------------------------------- 1 | # Terraform-Based Installation - Oracle Cloud Infrastructure Data Source for Grafana 2 | 3 | **NOTE**: There are aspects of this page that are out of date and need to be refreshed. The use of the steps laid out in this document may work as described. 4 | 5 | ## Background 6 | 7 | Grafana is a popular technology that makes it easy to visualize logs and metrics. The [Oracle Cloud Infrastructure Logs Data Source for Grafana](https://grafana.com/grafana/plugins/oci-logs-datasource/) is used to extend Grafana by adding OCI Logging as a data source. The plugin enables you to visualize log records (service, audit, and custom) and metrics derived from log records stored in the OCI Logging service. 8 | 9 | This walkthrough is intended for use by people who would like to deploy Grafana and the OCI Logs Data Source for Grafana on a virtual machine in OCI. 10 | 11 | Make sure you have access to the [Logging Service](https://docs.oracle.com/en-us/iaas/Content/Logging/Concepts/loggingoverview.htm) and that the logs you want to observe and analyze are being collected in your tenancy. See the OCI Logging documentation for information on how to collect or access: 12 | * [Logs from your compute instances](https://docs.oracle.com/en-us/iaas/Content/Logging/Concepts/agent_management.htm) 13 | * [Custom logs from your application/services](https://docs.oracle.com/en-us/iaas/Content/Logging/Concepts/custom_logs.htm) 14 | * [OCI service logs](https://docs.oracle.com/en-us/iaas/Content/Logging/Concepts/service_logs.htm). 15 | 16 | ## Install Terraform 17 | 18 | Begin by [installing Terraform](https://learn.hashicorp.com/terraform/getting-started/install) onto your development machine. We will be using the [Oracle Cloud Infrastructure Provider](https://www.terraform.io/docs/providers/oci/index.html), a tool designed to understand API interactions and exposing resource related to a specific cloud vendor, in this case Oracle Cloud Infrastructure. Terraform requires a number of variables in order to properly create an environment for Grafana and the OCI Data Source for Grafana plugin: 19 | 20 | ``` 21 | variable "tenancy_ocid" {} 22 | variable "user_ocid" {} 23 | variable "fingerprint" {} 24 | variable "private_key_path" {} 25 | variable "region" {} 26 | variable "compartment_ocid" {} 27 | variable "ssh_public_key" {} 28 | variable "ssh_private_key" {} 29 | variable "subnet_id" {} 30 | variable "availability_domain" {} 31 | variable "dynamic_group_name" {} 32 | ``` 33 | 34 | Information regarding how to find each of these variables is located [here](https://docs.cloud.oracle.com/iaas/Content/API/Concepts/apisigningkey.htm). It can be useful to pass these variables into your .bashrc or .bash_profile. You will need to enter a value for the availability domain of your subnet (e.g. PKGK:US-ASHBURN-AD-1). This information can be found under Networking > Virtual Cloud Networks > [Your Network] > Subnets. It will also prompt you for the name of your dynamic group (e.g. metric-collection). 35 | 36 | The Terraform script requires the use of an existing [Virtual Cloud Network](https://docs.cloud.oracle.com/iaas/Content/Network/Tasks/managingVCNs.htm) with access to the public internet. If you do not already have access to a Virtual Cloud Network with access to the public internet you can navigate to **Virtual Cloud Networks** under **Networking** and click **Create Virtual 37 | Cloud Network**. Choosing the **CREATE VIRTUAL CLOUD NETWORK PLUS RELATED RESOURCES** option will result in a VCN with an Internet Routing Gateway and Route Tables configured for access to the public internet. Three subnets will be created: one in each availability domain in the region. 38 | 39 | ![Screen Shot 2018-12-17 at 3.58.23 PM](images/Screen%20Shot%202018-12-17%20at%203.58.23%20PM.png) 40 | 41 | ## Create the Grafana Environment with Terraform 42 | 43 | After Terraform has been downloaded on your development machine, download the Terraform scripts here: `wget https://objectstorage.us-ashburn-1.oraclecloud.com/n/oracle-cloudnative/b/GrafanaTerraform/o/terraform_grafana.tar && tar -xvf terraform_grafana.tar` 44 | 45 | `cd /terraform_grafana`. Initialize a new Terraform configuration with `terraform init`. This will result in the creation of two additional files in the directory: `terraform.tfstate` and `terraform.tfstate.backup`. 46 | 47 | Next run `terraform plan` to generate an execution plan. This is useful to validate your Terraform script prior to applying it to your environment. The command will output the end state of your environment. 48 | 49 | ![Screen Shot 2018-12-17 at 3.59.38 PM](images/Screen%20Shot%202018-12-17%20at%203.59.38%20PM.png) 50 | 51 | Run `terraform apply` and enter the same availability domain and dynamic group name variables used in the previous step. This will build the infrastructure specified in the execution plan. The following three actions will take place: 52 | 53 | 1. The script will first create a [dynamic group](https://docs.cloud.oracle.com/iaas/Content/Identity/Tasks/managingdynamicgroups.htm) used to group virtual machine or bare metal compute instances as “principals” (similar to user groups). This will be named according to the variable you passed in during the previous step. 54 | 55 | ![Screen Shot 2018-12-17 at 4.01.34 PM](images/Screen%20Shot%202018-12-17%20at%204.01.34%20PM.png) 56 | 57 | 2. Next, a [policy](https://docs.cloud.oracle.com/iaas/Content/Identity/Concepts/policygetstarted.htm) named “grafana_policy” will be created in the root compartment of your tenancy to permit instances in the dynamic group to make API calls against Oracle Cloud Infrastructure services. 58 | 59 | ![Screen Shot 2018-12-17 at 4.01.47 PM](images/Screen%20Shot%202018-12-17%20at%204.01.47%20PM.png) 60 | 61 | 3. The script will then provision a [compute](https://docs.cloud.oracle.com/iaas/Content/Compute/Concepts/computeoverview.htm) instance with the name TFInstance0 in the compartment of your choice connected to the specified Virtual Cloud Network. After the instance is provisioned, the script will download and install Grafana and the Grafana OCI plugin. The plugin is stored in [Oracle Object Storage](https://docs.cloud.oracle.com/iaas/Content/Object/Concepts/objectstorageoverview.htm). 62 | 63 | ![Screen Shot 2018-12-17 at 4.04.42 PM](images/Screen%20Shot%202018-12-17%20at%204.04.42%20PM.png) 64 | 65 | Once the Terraform script is finished running you will receive an "Apply complete!" notification. 66 | 67 | ## Configure Grafana 68 | 69 | The next step is to configure the plugin. To find the IP address of the newly-created instance, navigate to Compute > Instances > TFInstance0. The Public IP address is listed under the Primary VNIC Information section. Using the SSH key referenced in your Terraform variables, connect to Grafana via port forward by running `ssh opc@[Instance Public IP] -L 3000:localhost:3000`. 70 | 71 | Navigate to the Grafana homepage at http://localhost:3000. 72 | 73 | ![GrafanaLogin-Screenshot](images/GrafanaLogin-Screenshot.png) 74 | 75 | Log in with the default username `admin` and the password `admin`. You will be prompted to change your password. Click **Skip** or **Save** to continue. 76 | 77 | ![Grafana-ChangeDefaultAdminPassword-Screenshot](images/Grafana-ChangeDefaultAdminPassword-Screenshot.png) 78 | 79 | On the Home Dashboard click the gear icon on the left side of the page and then select **Data sources** from the Configuration menu. 80 | 81 | ![GrafanaHomePage-Screenshot](images/GrafanaHomePage-Screenshot.png) 82 | 83 | Click **Add data source**. 84 | 85 | ![Grafana-AddDataSource-Screenshot](images/Grafana-AddDataSource-Screenshot.png) 86 | 87 | In the search box at the top of the resulting page, enter 'oracle'. 88 | 89 | ![Grafana-DataSourceSearch-Screenshot](images/Grafana-DataSourceSearch-Screenshot.png) 90 | 91 | Click the **Oracle Cloud Infrastructure Logs** box to select it as your data source type. 92 | 93 | ![Grafana-SelectOCILogsDataSource-Screenshot](images/Grafana-SelectOCILogsDataSource-Screenshot.png) 94 | 95 | On the Oracle Cloud Infrastructure Logs data source configuration page, fill in your **Tenancy OCID**, **Default Region**, and **Authentication Provider**. Your **Default region** is the same as your home region listed in the **Tenancy Details** page. For **Authentication Provider** choose **OCI Instance**. 96 | 97 | Click **Save & Test** to test the configuration of the Logs data source. Click the Dashboard icon in the left hand navigation menu to return to the home dashboard. 98 | 99 | ![Grafana-OCILogsPluginConfigWindow-Screenshot](images/Grafana-OCILogsPluginConfigWindow-Screenshot.png) 100 | 101 | ## Clean Up 102 | 103 | To remove the environment created by the Terraform script, run `terraform destroy` and pass in the same availability domain and dynamic group variables passed in during the apply step. 104 | 105 | 106 | ## Next Steps 107 | 108 | Check out how to use the newly installed and configured plugin in our [Using Grafana with Oracle Cloud Infrastructure Data Source](using.md) walkthrough. -------------------------------------------------------------------------------- /generate_region_list.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import re 3 | import datetime 4 | 5 | def fetch_and_process_regions(custom_regions=None): 6 | """ 7 | Fetches region data from the Oracle Cloud Infrastructure TypeScript SDK, 8 | processes it, and writes it to a TypeScript file. 9 | 10 | Args: 11 | custom_regions (list, optional): A list of custom regions to include. Defaults to None. 12 | Usage: 13 | python generate_region_list.py 14 | Warnings: 15 | This script will overwrite the content of ./src/regionlist.ts 16 | """ 17 | url = "https://raw.githubusercontent.com/oracle/oci-typescript-sdk/refs/heads/master/lib/common/lib/region.ts" 18 | response = requests.get(url) 19 | file_content = response.text 20 | 21 | matches = re.findall(r'Region\.register\("([^"]+)"', file_content) 22 | unique_sorted_matches = sorted(set(matches)) 23 | 24 | if custom_regions: 25 | unique_sorted_matches.extend(custom_regions) 26 | unique_sorted_matches = sorted(set(unique_sorted_matches)) 27 | 28 | # Format regions with each on its own line 29 | formatted_regions = ',\n '.join([f"'{region}'" for region in unique_sorted_matches]) 30 | regions = f"export const regions = [\n {formatted_regions}\n]" 31 | 32 | current_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") 33 | comment = ( 34 | "// This file is automatically generated from the Oracle Cloud Infrastructure TypeScript SDK.\n" 35 | f"// Source URL: {url}\n" 36 | "// Generated by script: generate_region_list.py (located in the repository root)\n" 37 | "// DO NOT EDIT MANUALLY. Use the generation script instead.\n" 38 | f"// Last updated: {current_time}\n" 39 | ) 40 | 41 | with open('./src/regionlist.ts', 'w') as file: 42 | file.write(comment + regions) 43 | 44 | print("Result successfully written to './src/regionlist.ts'") 45 | 46 | fetch_and_process_regions() 47 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/oracle/oci-grafana-logs 2 | 3 | go 1.23.0 4 | 5 | toolchain go1.23.7 6 | 7 | require ( 8 | github.com/davecgh/go-spew v1.1.1 9 | github.com/dgraph-io/ristretto v0.1.1 10 | github.com/grafana/grafana-plugin-sdk-go v0.250.0 11 | github.com/json-iterator/go v1.1.12 12 | github.com/oracle/oci-go-sdk/v65 v65.81.3 13 | github.com/pkg/errors v0.9.1 14 | ) 15 | 16 | require ( 17 | github.com/BurntSushi/toml v1.3.2 // indirect 18 | github.com/apache/arrow/go/v15 v15.0.2 // indirect 19 | github.com/beorn7/perks v1.0.1 // indirect 20 | github.com/cenkalti/backoff/v4 v4.3.0 // indirect 21 | github.com/cespare/xxhash/v2 v2.3.0 // indirect 22 | github.com/cheekybits/genny v1.0.0 // indirect 23 | github.com/chromedp/cdproto v0.0.0-20220208224320-6efb837e6bc2 // indirect 24 | github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect 25 | github.com/dustin/go-humanize v1.0.1 // indirect 26 | github.com/elazarl/goproxy v0.0.0-20230731152917-f99041a5c027 // indirect 27 | github.com/fatih/color v1.15.0 // indirect 28 | github.com/getkin/kin-openapi v0.124.0 // indirect 29 | github.com/go-logr/logr v1.4.2 // indirect 30 | github.com/go-logr/stdr v1.2.2 // indirect 31 | github.com/go-openapi/jsonpointer v0.20.2 // indirect 32 | github.com/go-openapi/swag v0.22.8 // indirect 33 | github.com/goccy/go-json v0.10.2 // indirect 34 | github.com/gofrs/flock v0.8.1 // indirect 35 | github.com/gogo/protobuf v1.3.2 // indirect 36 | github.com/golang/glog v1.2.4 // indirect 37 | github.com/golang/protobuf v1.5.4 // indirect 38 | github.com/google/flatbuffers v23.5.26+incompatible // indirect 39 | github.com/google/go-cmp v0.6.0 // indirect 40 | github.com/google/uuid v1.6.0 // indirect 41 | github.com/gorilla/mux v1.8.1 // indirect 42 | github.com/grafana/otel-profiling-go v0.5.1 // indirect 43 | github.com/grafana/pyroscope-go/godeltaprof v0.1.8 // indirect 44 | github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 // indirect 45 | github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 // indirect 46 | github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect 47 | github.com/hashicorp/go-hclog v1.6.3 // indirect 48 | github.com/hashicorp/go-plugin v1.6.1 // indirect 49 | github.com/hashicorp/yamux v0.1.1 // indirect 50 | github.com/invopop/yaml v0.2.0 // indirect 51 | github.com/josharian/intern v1.0.0 // indirect 52 | github.com/klauspost/compress v1.17.9 // indirect 53 | github.com/klauspost/cpuid/v2 v2.2.5 // indirect 54 | github.com/magefile/mage v1.15.0 // indirect 55 | github.com/mailru/easyjson v0.7.7 // indirect 56 | github.com/mattetti/filebuffer v1.0.1 // indirect 57 | github.com/mattn/go-colorable v0.1.13 // indirect 58 | github.com/mattn/go-isatty v0.0.19 // indirect 59 | github.com/mattn/go-runewidth v0.0.14 // indirect 60 | github.com/mitchellh/go-testing-interface v1.14.1 // indirect 61 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 62 | github.com/modern-go/reflect2 v1.0.2 // indirect 63 | github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect 64 | github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect 65 | github.com/oklog/run v1.1.0 // indirect 66 | github.com/olekukonko/tablewriter v0.0.5 // indirect 67 | github.com/perimeterx/marshmallow v1.1.5 // indirect 68 | github.com/pierrec/lz4/v4 v4.1.18 // indirect 69 | github.com/prometheus/client_golang v1.20.3 // indirect 70 | github.com/prometheus/client_model v0.6.1 // indirect 71 | github.com/prometheus/common v0.55.0 // indirect 72 | github.com/prometheus/procfs v0.15.1 // indirect 73 | github.com/rivo/uniseg v0.4.2 // indirect 74 | github.com/russross/blackfriday/v2 v2.1.0 // indirect 75 | github.com/sony/gobreaker v0.5.0 // indirect 76 | github.com/unknwon/bra v0.0.0-20200517080246-1e3013ecaff8 // indirect 77 | github.com/unknwon/com v1.0.1 // indirect 78 | github.com/unknwon/log v0.0.0-20150304194804-e617c87089d3 // indirect 79 | github.com/urfave/cli v1.22.15 // indirect 80 | github.com/zeebo/xxh3 v1.0.2 // indirect 81 | go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 // indirect 82 | go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.53.0 // indirect 83 | go.opentelemetry.io/contrib/propagators/jaeger v1.29.0 // indirect 84 | go.opentelemetry.io/contrib/samplers/jaegerremote v0.23.0 // indirect 85 | go.opentelemetry.io/otel v1.29.0 // indirect 86 | go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0 // indirect 87 | go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 // indirect 88 | go.opentelemetry.io/otel/metric v1.29.0 // indirect 89 | go.opentelemetry.io/otel/sdk v1.29.0 // indirect 90 | go.opentelemetry.io/otel/trace v1.29.0 // indirect 91 | go.opentelemetry.io/proto/otlp v1.3.1 // indirect 92 | golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect 93 | golang.org/x/mod v0.17.0 // indirect 94 | golang.org/x/net v0.36.0 // indirect 95 | golang.org/x/sync v0.11.0 // indirect 96 | golang.org/x/sys v0.30.0 // indirect 97 | golang.org/x/text v0.22.0 // indirect 98 | golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect 99 | golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect 100 | google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd // indirect 101 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect 102 | google.golang.org/grpc v1.66.0 // indirect 103 | google.golang.org/protobuf v1.34.2 // indirect 104 | gopkg.in/fsnotify/fsnotify.v1 v1.4.7 // indirect 105 | gopkg.in/yaml.v3 v3.0.1 // indirect 106 | ) 107 | -------------------------------------------------------------------------------- /jest-setup.js: -------------------------------------------------------------------------------- 1 | // Jest setup provided by Grafana scaffolding 2 | import './.config/jest-setup'; 3 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | // force timezone to UTC to allow tests to work regardless of local timezone 2 | // generally used by snapshots, but can affect specific tests 3 | process.env.TZ = 'UTC'; 4 | 5 | module.exports = { 6 | // Jest configuration provided by Grafana scaffolding 7 | ...require('./.config/jest.config'), 8 | }; 9 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "oci-logs-datasource", 3 | "private": true, 4 | "version": "5.0.2", 5 | "description": "Oracle Cloud Infrastructure Logs Data Source for Grafana", 6 | "scripts": { 7 | "build": "webpack -c ./.config/webpack/webpack.config.ts --env production", 8 | "dev": "webpack -w -c ./.config/webpack/webpack.config.ts --env development", 9 | "e2e": "yarn cypress install && yarn grafana-e2e run", 10 | "e2e:update": "yarn cypress install && yarn grafana-e2e run --update-screenshots", 11 | "server": "docker-compose up --build", 12 | "sign": "npx --yes @grafana/sign-plugin@latest", 13 | "start": "yarn watch", 14 | "test": "jest --watch --onlyChanged", 15 | "test:ci": "jest --passWithNoTests --maxWorkers 4", 16 | "typecheck": "tsc --noEmit", 17 | "lint": "eslint --cache --ignore-path ./.gitignore --ext .js,.jsx,.ts,.tsx .", 18 | "lint:fix": "yarn run lint --fix" 19 | }, 20 | "author": "", 21 | "license": "UPL-1.0", 22 | "engines": { 23 | "node": ">=16" 24 | }, 25 | "engineStrict": true, 26 | "devDependencies": { 27 | "@babel/core": "^7.24.1", 28 | "@babel/preset-react": "7.24.1", 29 | "@grafana/eslint-config": "^7.0.0", 30 | "@grafana/tsconfig": "^1.2.0-rc1", 31 | "@swc/core": "^1.3.90", 32 | "@swc/helpers": "^0.5.0", 33 | "@swc/jest": "^0.2.26", 34 | "@testing-library/jest-dom": "6.1.4", 35 | "@testing-library/react": "14.0.0", 36 | "@types/jest": "^29.5.0", 37 | "@types/lodash": "4.14.195", 38 | "@types/node": "^20.8.7", 39 | "@types/react-router-dom": "^5.2.0", 40 | "@types/testing-library__jest-dom": "5.14.8", 41 | "@typescript-eslint/parser": "^5.0.0", 42 | "babel-loader": "^8.0.2", 43 | "copy-webpack-plugin": "^11.0.0", 44 | "css-loader": "^6.7.3", 45 | "eslint-plugin-deprecation": "^2.0.0", 46 | "eslint-scope": "^5.1.1", 47 | "eslint-utils": "^2.1.0", 48 | "eslint-visitor-keys": "^2.1.0", 49 | "eslint-webpack-plugin": "^4.0.1", 50 | "fork-ts-checker-webpack-plugin": "^8.0.0", 51 | "glob": "^10.2.7", 52 | "identity-obj-proxy": "3.0.0", 53 | "imports-loader": "^5.0.0", 54 | "jest": "^29.7.0", 55 | "jest-environment-jsdom": "^29.5.0", 56 | "mocha": "6.x || 7.x || 8.x", 57 | "prettier": "^2.8.7", 58 | "prunk": "^1.3.0", 59 | "replace-in-file-webpack-plugin": "^1.0.6", 60 | "sass": "1.63.2", 61 | "sass-loader": "13.3.1", 62 | "style-loader": "3.3.3", 63 | "swc-loader": "^0.2.3", 64 | "ts-node": "^10.9.1", 65 | "tsconfig-paths": "^4.2.0", 66 | "typescript": "4.8.4", 67 | "webpack": "^5.94.0", 68 | "webpack-cli": "^5.1.4", 69 | "webpack-livereload-plugin": "^3.0.2" 70 | }, 71 | "dependencies": { 72 | "@apache-arrow/es5-cjs": "^4.0.1", 73 | "@babel/preset-env": "^7.3.4", 74 | "@emotion/css": "11.10.6", 75 | "@grafana/data": "^10.4.10", 76 | "@grafana/runtime": "^10.4.10", 77 | "@grafana/schema": "^10.4.10", 78 | "@grafana/ui": "^10.4.10", 79 | "eslint": "^9.6.0", 80 | "js-yaml": "^3.13.1", 81 | "lodash": "^4.17.21", 82 | "react": "18.2.0", 83 | "react-dom": "18.2.0", 84 | "tslib": "2.5.3" 85 | }, 86 | "resolutions": { 87 | "d3-color": "3.1.0" 88 | }, 89 | "packageManager": "yarn@1.22.21" 90 | } 91 | -------------------------------------------------------------------------------- /pkg/main.go: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright © 2023 Oracle and/or its affiliates. All rights reserved. 3 | ** Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. 4 | */ 5 | 6 | package main 7 | 8 | import ( 9 | "context" 10 | "os" 11 | 12 | "github.com/grafana/grafana-plugin-sdk-go/backend" 13 | "github.com/grafana/grafana-plugin-sdk-go/backend/datasource" 14 | "github.com/grafana/grafana-plugin-sdk-go/backend/instancemgmt" 15 | 16 | "github.com/oracle/oci-grafana-logs/pkg/plugin" 17 | ) 18 | 19 | const OCI_PLUGIN_ID = "oci-logs-datasource" 20 | 21 | func wrappedNewOCIDatasource(ctx context.Context, settings backend.DataSourceInstanceSettings) (instancemgmt.Instance, error) { 22 | return plugin.NewOCIDatasource(settings) // forward to original function 23 | } 24 | 25 | func main() { 26 | if err := datasource.Manage(OCI_PLUGIN_ID, wrappedNewOCIDatasource, datasource.ManageOpts{}); err != nil { 27 | backend.Logger.Error(err.Error()) 28 | os.Exit(1) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /pkg/plugin/constants/constants.go: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright © 2023 Oracle and/or its affiliates. All rights reserved. 3 | ** Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. 4 | */ 5 | 6 | package constants 7 | 8 | const ( 9 | DEFAULT_PROFILE = "DEFAULT/" 10 | DEFAULT_INSTANCE_PROFILE = "instance_profile" 11 | CACHE_KEY_RESOURCE_IDS_PER_TAG = "resourceIDsPerTag" 12 | ALL_REGION = "all-subscribed-region" 13 | FETCH_FOR_NAMESPACE = "namespace" 14 | ) 15 | const MaxPagesToFetch = 20 16 | const SingleTenancyKey = "DEFAULT/" 17 | const NoTenancy = "NoTenancy" 18 | 19 | // Constants for the log search result field names processed by the plugin 20 | const LogSearchResultsField_LogContent = "logContent" 21 | const LogSearchResultsField_Data = "data" 22 | const LogSearchResultsField_Oracle = "oracle" 23 | const LogSearchResultsField_Subject = "subject" 24 | const LogSearchResultsField_Time = "time" 25 | const LimitPerPage = 1000 26 | const numMaxResults = (MaxPagesToFetch * LimitPerPage) + 1 27 | const numMax1 = (MaxPagesToFetch * LimitPerPage) + 1 28 | 29 | // Constants for the log query data response field names 30 | const LogSearchResponseField_timestamp = "timestamp" 31 | 32 | const MaxLogMetricsDataPoints = 10 33 | const DefaultLogMetricsDataPoints = 5 34 | const MinLogMetricsDataPoints = 2 35 | 36 | type FieldValueType int 37 | 38 | const ( 39 | ValueType_Undefined FieldValueType = iota 40 | ValueType_Float64 41 | ValueType_Int 42 | ValueType_Time 43 | ValueType_String 44 | ) 45 | -------------------------------------------------------------------------------- /pkg/plugin/models/datasource_settings.go: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright © 2023 Oracle and/or its affiliates. All rights reserved. 3 | ** Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. 4 | */ 5 | 6 | package models 7 | 8 | import ( 9 | "fmt" 10 | 11 | "github.com/grafana/grafana-plugin-sdk-go/backend" 12 | jsoniter "github.com/json-iterator/go" 13 | 14 | "github.com/oracle/oci-grafana-logs/pkg/plugin/constants" 15 | ) 16 | 17 | // OCIDatasourceSettings holds the datasource configuration information for OCI 18 | type OCIDatasourceSettings struct { 19 | AuthProvider string `json:"authProvider"` 20 | ConfigProfile string `json:"configProfile"` 21 | TenancyMode string `json:"tenancymode"` 22 | TenancyName string `json:"tenancyName,omitempty"` 23 | Environment string `json:"environment"` 24 | 25 | Profile_0 string `json:"profile0,omitempty"` 26 | Region_0 string `json:"region0,omitempty"` 27 | 28 | Profile_1 string `json:"profile1,omitempty"` 29 | Region_1 string `json:"region1,omitempty"` 30 | 31 | Profile_2 string `json:"profile2,omitempty"` 32 | Region_2 string `json:"region2,omitempty"` 33 | 34 | Profile_3 string `json:"profile3,omitempty"` 35 | Region_3 string `json:"region3,omitempty"` 36 | 37 | Profile_4 string `json:"profile4,omitempty"` 38 | Region_4 string `json:"region4,omitempty"` 39 | 40 | Profile_5 string `json:"profile5,omitempty"` 41 | Region_5 string `json:"region5,omitempty"` 42 | 43 | Xtenancy_0 string `json:"xtenancy0,omitempty"` 44 | 45 | CustomRegion_0 string `json:"customregion0,omitempty"` 46 | CustomRegion_1 string `json:"customregion1,omitempty"` 47 | CustomRegion_2 string `json:"customregion2,omitempty"` 48 | CustomRegion_3 string `json:"customregion3,omitempty"` 49 | CustomRegion_4 string `json:"customregion4,omitempty"` 50 | CustomRegion_5 string `json:"customregion5,omitempty"` 51 | } 52 | 53 | // Load initializes the OCIDatasourceSettings from the provided backend.DataSourceInstanceSettings. 54 | // It unmarshals the JSONData from the DataSourceInstanceSettings into the OCIDatasourceSettings struct. 55 | // If the JSONData is not nil and has more than one element, it attempts to unmarshal it. 56 | // If unmarshalling fails, it returns an error indicating the failure. 57 | // Additionally, it sets the ConfigProfile to the default instance profile. 58 | // 59 | // Parameters: 60 | // - dsiSettings: backend.DataSourceInstanceSettings containing the settings to load. 61 | // 62 | // Returns: 63 | // - error: An error if the JSONData could not be unmarshalled, otherwise nil. 64 | func (d *OCIDatasourceSettings) Load(dsiSettings backend.DataSourceInstanceSettings) error { 65 | var err error 66 | 67 | if dsiSettings.JSONData != nil && len(dsiSettings.JSONData) > 1 { 68 | if err = jsoniter.Unmarshal(dsiSettings.JSONData, d); err != nil { 69 | return fmt.Errorf("could not unmarshal OCIDatasourceSettings json: %w", err) 70 | } 71 | } 72 | 73 | // in case of instance principle auth provider 74 | d.ConfigProfile = constants.DEFAULT_INSTANCE_PROFILE 75 | 76 | return nil 77 | } 78 | -------------------------------------------------------------------------------- /pkg/plugin/models/http_error.go: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright © 2023 Oracle and/or its affiliates. All rights reserved. 3 | ** Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. 4 | */ 5 | 6 | package models 7 | 8 | type HttpError struct { 9 | Message string 10 | Error string 11 | StatusCode int 12 | } 13 | -------------------------------------------------------------------------------- /pkg/plugin/models/oci.go: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright © 2023 Oracle and/or its affiliates. All rights reserved. 3 | ** Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. 4 | */ 5 | 6 | package models 7 | 8 | // OCIResource represents a generic OCI resource with a name and OCID. 9 | type OCIResource struct { 10 | // Name is the display name of the OCI resource. 11 | Name string `json:"name,omitempty"` 12 | // OCID is the Oracle Cloud Identifier of the OCI resource. 13 | OCID string `json:"ocid,omitempty"` 14 | } 15 | 16 | // The label fields for the log metric representing key-value metadata for a label. 17 | type LabelFieldMetadata struct { 18 | LabelName string 19 | LabelValue string 20 | } 21 | 22 | // GrafanaCommonRequest represents a common request structure for Grafana queries. 23 | type GrafanaCommonRequest struct { 24 | Environment string // The environment in which the request is being executed (e.g., dev, prod). 25 | TenancyMode string // The mode of tenancy (e.g., single-tenant or multi-tenant). 26 | QueryType string // The type of query being executed (e.g., metrics, logs, alerts). 27 | Region string // The OCI region where the request is being processed (e.g., us-phoenix-1). 28 | Tenancy string // the actual tenancy with the format 29 | TenancyOCID string `json:"tenancyOCID"` // The unique OCID of the tenancy, used for identification. 30 | } 31 | 32 | // GrafanaSearchLogsRequest represents a request to search logs in Grafana. 33 | type GrafanaSearchLogsRequest struct { 34 | GrafanaCommonRequest // Embeds common request fields such as Environment, Region, and Tenancy. 35 | SearchQuery string // The query string used to filter logs. 36 | MaxDataPoints int32 // The maximum number of data points to return in the response. 37 | PanelId string // The ID of the Grafana panel requesting the log data. 38 | } 39 | -------------------------------------------------------------------------------- /pkg/plugin/models/query.go: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright © 2023 Oracle and/or its affiliates. All rights reserved. 3 | ** Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. 4 | */ 5 | 6 | package models 7 | 8 | // QueryModel ... 9 | type QueryModel struct { 10 | QueryText string `json:"searchQuery"` 11 | TenancyName string `json:"tenancyName"` 12 | TenancyOCID string `json:"tenancy"` 13 | Region string `json:"region"` 14 | } 15 | -------------------------------------------------------------------------------- /pkg/plugin/models/request.go: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright © 2023 Oracle and/or its affiliates. All rights reserved. 3 | ** Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. 4 | */ 5 | 6 | package models 7 | -------------------------------------------------------------------------------- /pkg/plugin/query.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2023 Oracle and/or its affiliates. All rights reserved. 2 | // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. 3 | 4 | package plugin 5 | 6 | import ( 7 | "context" 8 | "encoding/json" 9 | "time" 10 | 11 | "github.com/grafana/grafana-plugin-sdk-go/backend" 12 | 13 | "github.com/oracle/oci-grafana-logs/pkg/plugin/models" 14 | ) 15 | 16 | // query processes a data query for the OCIDatasource, executing the necessary operations based on the query type and time range. 17 | // It identifies the query type (Log Metrics or Log Records) and invokes the corresponding method to process the data. 18 | // 19 | // Parameters: 20 | // - ctx (context.Context): The context for the query execution, typically used for cancellation or deadlines. 21 | // - pCtx (backend.PluginContext): The plugin context, providing access to the plugin environment and configuration. 22 | // - query (backend.DataQuery): The data query to be executed, which contains the query text and time range. 23 | // 24 | // Returns: 25 | // - map[string]*DataFieldElements: A map containing the processed data field elements, which will be included in the query response. 26 | // - backend.DataResponse: A response struct containing any errors encountered during query processing. 27 | // 28 | // Function Behavior: 29 | // - The function begins by unmarshalling the query's JSON into a QueryModel object. 30 | // - It identifies the query type (Log Metrics Time Series, Log Metrics No Interval, or Log Records) based on the query text. 31 | // - Depending on the query type, it calls the appropriate method to process the log data (e.g., `processLogMetricTimeSeries`, `processLogMetrics`, or `processLogRecords`). 32 | // - If an error occurs during processing, it is returned in the response. The function ensures proper handling of different query types to return the correct data format for the client. 33 | func (ocidx *OCIDatasource) query(ctx context.Context, pCtx backend.PluginContext, query backend.DataQuery) (map[string]*DataFieldElements, backend.DataResponse) { 34 | backend.Logger.Debug("plugin.query", "query", "query initiated for "+query.RefID) 35 | // Creating the Data response for query 36 | response := backend.DataResponse{} 37 | //response := backend.NewQueryDataResponse() 38 | // Unmarshal the json into oci queryModel 39 | qm := &models.QueryModel{} 40 | response.Error = json.Unmarshal(query.JSON, &qm) 41 | if response.Error != nil { 42 | return nil, response 43 | } 44 | 45 | takey := ocidx.GetTenancyAccessKey(qm.TenancyOCID) 46 | 47 | logQueryType := ocidx.identifyQueryType(qm.QueryText) 48 | 49 | var processErr error 50 | fromMs := query.TimeRange.From.UnixNano() / int64(time.Millisecond) 51 | toMs := query.TimeRange.To.UnixNano() / int64(time.Millisecond) 52 | var mFieldData = make(map[string]*DataFieldElements) 53 | 54 | if logQueryType == QueryType_LogMetrics_TimeSeries { 55 | ocidx.logger.Debug("Logging query WILL return numeric data over intervals", "refId", query.RefID) 56 | // Call method that parses log metric results and produces the required field definitions 57 | mFieldData, processErr = ocidx.processLogMetricTimeSeries(ctx, query, qm, fromMs, toMs, mFieldData, takey) 58 | } else if logQueryType == QueryType_LogMetrics_NoInterval { 59 | ocidx.logger.Debug("Logging query will NOT return numeric data over entire time range", "refId", query.RefID) 60 | // Call method that parses log metric results and produces the required field definitions 61 | mFieldData, processErr = ocidx.processLogMetrics(ctx, query, qm, fromMs, toMs, mFieldData, takey) 62 | 63 | } else { // QueryType_LogRecords 64 | ocidx.logger.Debug("Logging query will return log records for the specified time interval", "refId", query.RefID) 65 | // Call method that parses log record results and produces the required field definitions 66 | mFieldData, processErr = ocidx.processLogRecords(ctx, query, qm, fromMs, toMs, mFieldData, takey) 67 | } 68 | if processErr != nil { 69 | response.Error = processErr 70 | return nil, response 71 | } 72 | 73 | return mFieldData, response 74 | } 75 | -------------------------------------------------------------------------------- /pkg/plugin/resource_handler.go: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright © 2023 Oracle and/or its affiliates. All rights reserved. 3 | ** Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. 4 | */ 5 | 6 | package plugin 7 | 8 | import ( 9 | "net/http" 10 | 11 | "github.com/grafana/grafana-plugin-sdk-go/backend" 12 | jsoniter "github.com/json-iterator/go" 13 | 14 | "github.com/oracle/oci-grafana-logs/pkg/plugin/models" 15 | ) 16 | 17 | // rootRequest defines the structure for requests that only require a tenancy OCID. 18 | type rootRequest struct { 19 | Tenancy string `json:"tenancy"` 20 | } 21 | 22 | // queryRequest defines the structure for requests to execute a query on a specific tenancy. 23 | type queryRequest struct { 24 | Tenancy string `json:"tenancy"` // The OCID of the tenancy 25 | Region string `json:"region"` // The region of the tenancy 26 | Query string `json:"getquery"` // The query to be executed 27 | Field string `json:"field"` // Specific field for the query 28 | TimeStart int64 `json:"timeStart"` // The start timestamp of the time range for the query (in milliseconds) 29 | TimeEnd int64 `json:"timeEnd"` // The end timestamp of the time range for the query (in milliseconds) 30 | } 31 | 32 | // registerRoutes registers the HTTP routes and their corresponding handler functions. 33 | // Parameters: 34 | // - mux: *http.ServeMux - The multiplexer that routes HTTP requests to the appropriate handlers. 35 | func (ocidx *OCIDatasource) registerRoutes(mux *http.ServeMux) { 36 | mux.HandleFunc("/tenancies", ocidx.GetTenanciesHandler) 37 | mux.HandleFunc("/regions", ocidx.GetRegionsHandler) 38 | mux.HandleFunc("/getquery", ocidx.GetQueryHandler) 39 | } 40 | 41 | // GetTenanciesHandler handles GET requests for retrieving a list of tenancies. 42 | // Parameters: 43 | // - rw: http.ResponseWriter - The response writer to send the response to the client. 44 | // - req: *http.Request - The incoming HTTP request containing the details for the request. 45 | func (ocidx *OCIDatasource) GetTenanciesHandler(rw http.ResponseWriter, req *http.Request) { 46 | if req.Method != http.MethodGet { 47 | respondWithError(rw, http.StatusMethodNotAllowed, "Invalid method", nil) 48 | return 49 | } 50 | 51 | // ts := ocidx.clients.GetTenancies(req.Context()) 52 | ts := ocidx.GetTenancies(req.Context()) 53 | backend.Logger.Debug("plugin.resource_handler", "GetTenanciesHandler", ts) 54 | writeResponse(rw, ts) 55 | } 56 | 57 | // GetRegionsHandler handles POST requests for retrieving a list of regions for a specific tenancy. 58 | // Parameters: 59 | // - rw: http.ResponseWriter - The response writer to send the response to the client. 60 | // - req: *http.Request - The incoming HTTP request containing the tenancy OCID in the body. 61 | func (ocidx *OCIDatasource) GetRegionsHandler(rw http.ResponseWriter, req *http.Request) { 62 | if req.Method != http.MethodPost { 63 | respondWithError(rw, http.StatusMethodNotAllowed, "Invalid method", nil) 64 | return 65 | } 66 | 67 | var rr rootRequest 68 | if err := jsoniter.NewDecoder(req.Body).Decode(&rr); err != nil { 69 | backend.Logger.Error("plugin.resource_handler", "GetRegionsHandler", err) 70 | respondWithError(rw, http.StatusBadRequest, "Failed to read request body", err) 71 | return 72 | } 73 | // Fetch subscribed regions for the specified tenancy OCID 74 | regions := ocidx.GetSubscribedRegions(req.Context(), rr.Tenancy) 75 | if regions == nil { 76 | backend.Logger.Error("plugin.resource_handler", "GetSubscribedRegions", "Could not read regions") 77 | respondWithError(rw, http.StatusBadRequest, "Could not read regions", nil) 78 | return 79 | } 80 | backend.Logger.Debug("plugin.resource_handler", "GetRegionsHandler", regions) 81 | writeResponse(rw, regions) 82 | } 83 | 84 | // GetQueryHandler handles POST requests for querying logs based on the provided parameters. 85 | // Parameters: 86 | // - rw: http.ResponseWriter - The response writer to send the response to the client. 87 | // - req: *http.Request - The incoming HTTP request containing the query details (Tenancy, Region, Query, Field, TimeStart, TimeEnd). 88 | func (ocidx *OCIDatasource) GetQueryHandler(rw http.ResponseWriter, req *http.Request) { 89 | if req.Method != http.MethodPost { 90 | respondWithError(rw, http.StatusMethodNotAllowed, "Invalid method", nil) 91 | return 92 | } 93 | 94 | var rr queryRequest 95 | if err := jsoniter.NewDecoder(req.Body).Decode(&rr); err != nil { 96 | backend.Logger.Error("plugin.resource_handler", "GetQueryHandler", err) 97 | respondWithError(rw, http.StatusBadRequest, "Failed to read request body", err) 98 | return 99 | } 100 | 101 | // Execute the query and fetch results based on the parameters 102 | resp, err := ocidx.getLogs(req.Context(), rr.Tenancy, rr.Query, rr.Field, rr.TimeStart, rr.TimeEnd) 103 | if err != nil { 104 | backend.Logger.Error("plugin.resource_handler", "GetQueryHandler", err) 105 | respondWithError(rw, http.StatusBadRequest, "Could not run query", err) 106 | return 107 | } 108 | 109 | if resp == nil { 110 | backend.Logger.Error("plugin.resource_handler", "GetQueryHandler", "Query Result is empty") 111 | respondWithError(rw, http.StatusBadRequest, "Query Result is empty", nil) 112 | return 113 | } 114 | backend.Logger.Debug("plugin.resource_handler", "GetQueryHandler", resp) 115 | writeResponse(rw, resp) 116 | } 117 | 118 | // writeResponse writes a successful JSON response to the http.ResponseWriter. 119 | // 120 | // Parameters: 121 | // - rw: http.ResponseWriter to write the response. 122 | // - resp: interface{} representing the data to be written as JSON. 123 | func writeResponse(rw http.ResponseWriter, resp interface{}) { 124 | resultJson, err := jsoniter.Marshal(resp) 125 | if err != nil { 126 | backend.Logger.Error("plugin.resource_handler", "writeResponse", "could not parse response:"+err.Error()) 127 | respondWithError(rw, http.StatusInternalServerError, "Failed to convert result", err) 128 | } 129 | 130 | sendResponse(rw, http.StatusOK, resultJson) 131 | } 132 | 133 | // respondWithError writes an error JSON response to the http.ResponseWriter. 134 | // 135 | // Parameters: 136 | // - rw: http.ResponseWriter to write the response. 137 | // - statusCode: int representing the HTTP status code. 138 | // - message: string representing the error message. 139 | // - err: error representing the error object (optional). 140 | func respondWithError(rw http.ResponseWriter, statusCode int, message string, err error) { 141 | httpError := &models.HttpError{ 142 | Message: message, 143 | StatusCode: statusCode, 144 | } 145 | if err != nil { 146 | httpError.Error = err.Error() 147 | } 148 | 149 | response, err := jsoniter.Marshal(httpError) 150 | if err != nil { 151 | backend.Logger.Error("plugin.resource_handler", "respondWithError", "could not parse response:"+err.Error()) 152 | rw.WriteHeader(http.StatusInternalServerError) 153 | return 154 | } 155 | 156 | sendResponse(rw, statusCode, response) 157 | } 158 | 159 | // sendResponse writes the given JSON response to the http.ResponseWriter with the specified status code. 160 | // 161 | // Parameters: 162 | // - rw: http.ResponseWriter to write the response. 163 | // - statusCode: int representing the HTTP status code. 164 | // - response: []byte representing the JSON response. 165 | func sendResponse(rw http.ResponseWriter, statusCode int, response []byte) { 166 | rw.Header().Set("Content-Type", "application/json") 167 | rw.WriteHeader(statusCode) 168 | 169 | _, err := rw.Write(response) 170 | if err != nil { 171 | backend.Logger.Error("plugin.resource_handler", "sendResponse", "could not write to response: "+err.Error()) 172 | rw.WriteHeader(http.StatusInternalServerError) 173 | } 174 | } 175 | -------------------------------------------------------------------------------- /pkg/plugin/utils.go: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright © 2023 Oracle and/or its affiliates. All rights reserved. 3 | ** Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. 4 | */ 5 | 6 | package plugin 7 | 8 | import ( 9 | "bytes" 10 | "encoding/json" 11 | "fmt" 12 | "strings" 13 | 14 | "github.com/grafana/grafana-plugin-sdk-go/backend" 15 | "github.com/pkg/errors" 16 | ) 17 | 18 | // Prepare format to decode SecureJson 19 | func transcode(in, out interface{}) { 20 | buf := new(bytes.Buffer) 21 | json.NewEncoder(buf).Encode(in) 22 | json.NewDecoder(buf).Decode(out) 23 | } 24 | 25 | // GetTenancyAccessKey retrieves the tenancy access key based on the tenancy mode. 26 | // If the tenancy mode is "multitenancy", it uses the provided tenancyOCID as the key. 27 | // Otherwise, it uses a predefined SingleTenancyKey. 28 | // It logs an error if the key is invalid and returns an empty string in that case. 29 | // 30 | // Parameters: 31 | // 32 | // tenancyOCID (string): The OCID of the tenancy. 33 | // 34 | // Returns: 35 | // 36 | // string: The tenancy access key if valid, otherwise an empty string. 37 | func (o *OCIDatasource) GetTenancyAccessKey(tenancyOCID string) string { 38 | 39 | // Determine the tenancy access key based on the tenancy mode. 40 | var takey string 41 | tenancymode := o.settings.TenancyMode 42 | if tenancymode == "multitenancy" { 43 | takey = tenancyOCID 44 | } else { 45 | takey = SingleTenancyKey 46 | } 47 | 48 | // Check if the tenancy access key is valid. 49 | _, ok := o.tenancyAccess[takey] 50 | if ok { 51 | backend.Logger.Debug("GetTenancyAccessKey", "GetTenancyAccessKey", "valid takey: "+takey) 52 | } else { 53 | backend.Logger.Error("GetTenancyAccessKey", "GetTenancyAccessKey", "Invalid takey: "+takey) 54 | return "" 55 | } 56 | 57 | // Return the tenancy access key. 58 | return takey 59 | } 60 | 61 | // FilterMap filters through a map of type map[string]interface{} and returns the first value 62 | // found that is not associated with the keys "datetime" or "count". If a valid key-value pair 63 | // is found, the value is returned as a string. If no such valid key is found, an error is returned. 64 | // 65 | // Parameters: 66 | // - inputMap: An interface{} that is expected to be a map of type map[string]interface{}. 67 | // 68 | // Returns: 69 | // - A string representing the first value found in the map that is not associated with 70 | // the keys "datetime" or "count". 71 | // - An error if the input is not of type map[string]interface{} or if no valid key is found. 72 | func FilterMap(inputMap interface{}) (string, error) { 73 | // Check if the input is a map[string]interface{}. 74 | m, ok := inputMap.(map[string]interface{}) 75 | if !ok { 76 | return "", fmt.Errorf("input is not a map[string]interface{}") 77 | } 78 | 79 | // Iterate over the map. 80 | for key, value := range m { 81 | // If the key is not "datetime" or "count", return the value. 82 | if key != "datetime" && key != "count" { 83 | return fmt.Sprintf("%v", value), nil 84 | } 85 | } 86 | 87 | // No valid key was found in the map. 88 | return "", errors.New("no valid key found in the map") 89 | } 90 | 91 | // uniqueStrings removes duplicate strings from a slice, returning a new slice 92 | // containing only unique strings in the order they first appear. 93 | // 94 | // Parameters: 95 | // - slice: A slice of strings where duplicates will be removed. 96 | // 97 | // Returns: 98 | // - A new slice containing only the unique strings from the input slice, 99 | // in the order they first appeared. 100 | func uniqueStrings(slice []string) []string { 101 | // Create a map to keep track of seen strings. 102 | seen := make(map[string]struct{}) 103 | 104 | // Create a new list to store unique strings. 105 | unique := []string{} 106 | 107 | // Iterate over the slice. 108 | for _, str := range slice { 109 | // Check if the string has been seen before. 110 | if _, ok := seen[str]; !ok { 111 | // Add the string to the map. 112 | seen[str] = struct{}{} 113 | 114 | // Add the string to the unique list. 115 | unique = append(unique, str) 116 | } 117 | } 118 | 119 | // Return the list of unique strings. 120 | return unique 121 | } 122 | 123 | // extractField extracts the value of a specified field from a JSON string. 124 | // It unmarshals the JSON string into a map and returns the value of the specified field. 125 | // 126 | // Parameters: 127 | // - jsonStr: A string containing the JSON data. 128 | // - field: The name of the field whose value should be extracted from the JSON. 129 | // 130 | // Returns: 131 | // - A string containing the value of the specified field, or an error if the field is not found 132 | // or if there is an issue with unmarshaling the JSON. 133 | // 134 | // Errors: 135 | // - If the JSON string cannot be unmarshaled, or if the field is not found in the JSON, an error is returned. 136 | func extractField(jsonStr string, field string) (string, error) { 137 | // Unmarshal the JSON string into a map. 138 | var data map[string]interface{} 139 | field = strings.Trim(field, "\\\"") 140 | err := json.Unmarshal([]byte(jsonStr), &data) 141 | if err != nil { 142 | return "", fmt.Errorf("error unmarshaling JSON: %v", err) 143 | } 144 | 145 | // Check if the field exists in the map. 146 | value, ok := data[field] 147 | if !ok { 148 | return "", errors.New("field not found in JSON " + field) 149 | } 150 | 151 | // Convert the value to a string and return it. 152 | return fmt.Sprintf("%v", value), nil 153 | } 154 | -------------------------------------------------------------------------------- /sbom_generation.yaml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. 2 | 3 | # This OCI DevOps build specification file [1] generates a Software Bill of Materials (SBOM) of the repository. 4 | # The file is needed to run checks for third-party vulnerabilities and business approval according to Oracle’s GitHub policies. 5 | # [1] https://docs.oracle.com/en-us/iaas/Content/devops/using/build_specs.htm 6 | 7 | version: 0.1 8 | component: build 9 | timeoutInSeconds: 1000 10 | shell: bash 11 | 12 | steps: 13 | - type: Command 14 | name: "Install dependencies & cyclonedx-node-npm package" 15 | command: | 16 | npm install && npm install --save-dev @cyclonedx/cyclonedx-npm@1.19.3 17 | - type: Command 18 | name: "Run cyclonedx-node-npm package" 19 | command: | 20 | # For more details, visit https://github.com/CycloneDX/cyclonedx-node-npm/blob/main/README.md 21 | npx @cyclonedx/cyclonedx-npm --omit dev --output-format JSON --output-file npm_artifactSBOM.json --spec-version 1.4 --flatten-components 22 | - type: Command 23 | name: "Download the version 10.10.0 of cdxgen globally" 24 | command: | 25 | npm install -g @cyclonedx/cdxgen@10.10.0 26 | - type: Command 27 | name: "Workaround to let cdxgen run on nodejs 16" 28 | command: | 29 | # cdxgen relies on a fourth-party dependency that cannot be executed in a Node.js environment running version 16 30 | # (as installed on the build runner instance) 31 | # This is a workaround to ensure cdxgen functions correctly, even in an older Node.js environment. 32 | cd /node/node-v16.14.2-linux-x64/lib/node_modules/@cyclonedx/cdxgen && \ 33 | npm install cheerio@v1.0.0-rc.12 34 | - type: Command 35 | name: "Generate SBOM for Golang " 36 | command: | 37 | # the version of go should be the same in go.mod or greater 38 | GO_VERSION="1.22.3" && \ 39 | INSTALL_DIR="${OCI_PRIMARY_SOURCE_DIR}" && \ 40 | curl -L -o go-${GO_VERSION}.tar.gz https://go.dev/dl/go${GO_VERSION}.linux-amd64.tar.gz && \ 41 | tar -C ${INSTALL_DIR} -xzf go-${GO_VERSION}.tar.gz && \ 42 | export GOROOT=${INSTALL_DIR}/go && \ 43 | export PATH=${GOROOT}/bin:${PATH} && \ 44 | go mod tidy && \ 45 | cdxgen -t golang -o golang_artifactSBOM.json --spec-version 1.4 --project-name "$(basename $OCI_PRIMARY_SOURCE_URL)" --no-recurse && \ 46 | - type: Command 47 | name: "Download CycloneDx-cli executable and install dependencies" 48 | command: | 49 | wget https://github.com/CycloneDX/cyclonedx-cli/releases/download/v0.24.2/cyclonedx-linux-x64 50 | yum install -y libicu 51 | - type: Command 52 | name: "Merge multiple SBOMs using CycloneDX-cli" 53 | command: | 54 | # For more details, visit https://github.com/CycloneDX/cyclonedx-cli/blob/main/README.md 55 | chmod +x cyclonedx-linux-x64 56 | ./cyclonedx-linux-x64 merge --input-files npm_artifactSBOM.json,golang_artifactSBOM.json --output-file merged-bom.json 57 | outputArtifacts: 58 | - name: artifactSBOM 59 | type: BINARY 60 | location: ${OCI_PRIMARY_SOURCE_DIR}/merged-bom.json -------------------------------------------------------------------------------- /src/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../.config/.eslintrc" 3 | } -------------------------------------------------------------------------------- /src/QueryEditor.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright © 2023 Oracle and/or its affiliates. All rights reserved. 3 | ** Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. 4 | */ 5 | 6 | import React, {KeyboardEvent, useEffect, useState } from 'react'; 7 | import { InlineField, InlineFieldRow, FieldSet, SegmentAsync, Input, TextArea } from '@grafana/ui'; 8 | import { QueryEditorProps, SelectableValue } from '@grafana/data'; 9 | import { getTemplateSrv } from '@grafana/runtime'; 10 | import { OCIDataSource } from './datasource'; 11 | import { OCIDataSourceOptions, OCIQuery, QueryPlaceholder } from './types'; 12 | //import QueryModel from './query_model'; 13 | import { TenancyChoices } from './config.options'; 14 | 15 | type Props = QueryEditorProps; 16 | 17 | /** 18 | * QueryEditor component. 19 | * 20 | * This component allows users to configure and execute queries by selecting 21 | * tenancy, region, and entering a search query. 22 | * 23 | * Features: 24 | * - Supports both single-tenancy and multi-tenancy modes. 25 | * - Fetches available tenancies and subscribed regions dynamically. 26 | * - Provides an input field for query entry. 27 | * - Allows execution of queries with keyboard shortcuts (Shift+Enter or Ctrl+Enter). 28 | * 29 | * Props: 30 | * @param {Props} props - The component properties. 31 | * @param {OCIQuery} props.query - The current query object. 32 | * @param {OCIDataSource} props.datasource - The OCI data source instance. 33 | * @param {Function} props.onChange - Callback for updating the query state. 34 | * @param {Function} props.onRunQuery - Callback for executing the query. 35 | * 36 | * Returns: 37 | * A React component that renders the query editor UI for the OCI data source. 38 | */ 39 | 40 | export const QueryEditor: React.FC = (props) => { 41 | const { query, datasource, onChange, onRunQuery } = props; 42 | const tmode = datasource.getJsonData().tenancymode; 43 | const [hasLegacyTenancy, setHasLegacyTenancy] = useState(false); 44 | const [tenancyValue, setTenancyValue] = useState(query.tenancyName); 45 | const [regionValue, setRegionValue] = useState(query.region); 46 | const [hasCalledGetTenancyDefault, setHasCalledGetTenancyDefault] = useState(false); 47 | 48 | /** 49 | * Handles keydown events in the query input field. 50 | * 51 | * Triggers the query execution when the user presses "Enter" while holding 52 | * the "Shift" or "Ctrl" key. Prevents the default behavior to avoid unintended 53 | * newlines in the input field. 54 | * 55 | * @param {KeyboardEvent} event - The keydown event object. 56 | */ 57 | const onKeyDown = (event: KeyboardEvent) => { 58 | if (event.key === 'Enter' && (event.shiftKey || event.ctrlKey)) { 59 | event.preventDefault(); 60 | onRunQuery(); 61 | } 62 | }; 63 | 64 | /** 65 | * Updates the query state and optionally triggers the query execution. 66 | * 67 | * If `runQuery` is `true`, additional logic can be added to process or validate 68 | * the query before running it. If `runQuery` is `false`, the function only updates 69 | * the query state without executing it. 70 | * 71 | * @param {OCIQuery} changedQuery - The modified query object. 72 | * @param {boolean} [runQuery=true] - Whether to trigger query execution after applying changes. 73 | */ 74 | const onApplyQueryChange = (changedQuery: OCIQuery, runQuery = true) => { 75 | if (runQuery) { 76 | /* TODO: Add some logic*/ 77 | } else { 78 | onChange({ ...changedQuery }); 79 | } 80 | }; 81 | /** 82 | * addTemplateVariablesToOptions 83 | * 84 | * Appends all available template variables to options used by dropdowns. 85 | * 86 | * @param options - The array of SelectableValue options to which template variables will be added. 87 | * @returns The updated array of SelectableValue options. 88 | */ 89 | const addTemplateVariablesToOptions = (options: Array>) => { 90 | getTemplateSrv() 91 | .getVariables() 92 | .forEach((item) => { 93 | options.push({ 94 | label: `$${item.name}`, 95 | value: `$${item.name}`, 96 | }); 97 | }); 98 | return options; 99 | } 100 | 101 | /** 102 | * CustomInput Component 103 | * 104 | * A custom input field for Single Tenancy Mode, pre-filling the tenancy with "DEFAULT/". 105 | */ 106 | const CustomInput = ({ ...props }) => { 107 | const [isReady, setIsReady] = useState(false); 108 | 109 | useEffect(() => { 110 | if (!hasCalledGetTenancyDefault && isReady) { 111 | const getTenancyDefault = async () => { 112 | const tname = 'DEFAULT/'; 113 | const tvalue = 'DEFAULT/'; 114 | onApplyQueryChange({ ...query, tenancyName: tname, tenancy: tvalue }, false); 115 | setHasCalledGetTenancyDefault(true); 116 | }; 117 | getTenancyDefault(); 118 | } 119 | }, [isReady]); 120 | 121 | useEffect(() => { 122 | setIsReady(true); 123 | }, []); 124 | 125 | return ; 126 | }; 127 | 128 | /** 129 | * getTenancyOptions 130 | * 131 | * Fetches the available tenancies from the data source. 132 | * 133 | * @returns A promise that resolves to an array of SelectableValue options representing the tenancies. 134 | */ 135 | const getTenancyOptions = async () => { 136 | let options: Array> = []; 137 | options = addTemplateVariablesToOptions(options) 138 | const response = await datasource.getTenancies(); 139 | if (response) { 140 | response.forEach((item: any) => { 141 | const sv: SelectableValue = { 142 | label: item.name, 143 | value: item.ocid, 144 | }; 145 | options.push(sv); 146 | }); 147 | } 148 | return options; 149 | }; 150 | 151 | /** 152 | * getSubscribedRegionOptions 153 | * 154 | * Fetches the subscribed regions for the selected tenancy from the data source. 155 | * 156 | * @returns A promise that resolves to an array of SelectableValue options representing the regions. 157 | */ 158 | const getSubscribedRegionOptions = async () => { 159 | let options: Array> = []; 160 | options = addTemplateVariablesToOptions(options) 161 | const response = await datasource.getSubscribedRegions(query.tenancy); 162 | if (response) { 163 | response.forEach((item: string) => { 164 | const sv: SelectableValue = { 165 | label: item, 166 | value: item, 167 | }; 168 | options.push(sv); 169 | }); 170 | } 171 | return options; 172 | }; 173 | 174 | /** 175 | * onTenancyChange 176 | * 177 | * Handles changes to the selected tenancy. 178 | * 179 | * @param data - The selected tenancy data. 180 | */ 181 | const onTenancyChange = async (data: any) => { 182 | setTenancyValue(data); 183 | onApplyQueryChange( 184 | { 185 | ...query, 186 | tenancyName: data.label, 187 | tenancy: data.value, 188 | region: undefined, 189 | }, 190 | false 191 | ); 192 | }; 193 | 194 | /** 195 | * onRegionChange 196 | * 197 | * Handles the change of the region selection. 198 | * 199 | * @param {SelectableValue} data - The selected region data. 200 | */ 201 | const onRegionChange = (data: SelectableValue) => { 202 | setRegionValue(data.value); 203 | onApplyQueryChange({ ...query, region: data.value}, false); 204 | }; 205 | 206 | // set tenancyName in case dashboard was created with version 4.x 207 | if (query.tenancy && !hasLegacyTenancy && !query.tenancyName) { 208 | query.tenancyName = query.tenancy; 209 | setTenancyValue(query.tenancy); 210 | setHasLegacyTenancy(true); 211 | } 212 | 213 | return ( 214 | <> 215 |
216 | 217 | {tmode === TenancyChoices.multitenancy && ( 218 | <> 219 | 220 | { 228 | onTenancyChange(data); 229 | }} 230 | /> 231 | 232 | 233 | )} 234 | {tmode === TenancyChoices.single && ( 235 | <> 236 | 237 | 238 | 239 | 240 | )} 241 | 242 | 243 | 244 | { 252 | onRegionChange(data); 253 | }} 254 | /> 255 | 256 | 257 | 261 |