Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: bring back browser extension #1152

Closed
wants to merge 21 commits into from
Closed
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
2b2b62a
feat: bring back browser extension
svrnm Sep 5, 2022
1328baa
fix: lint errors with browser extension
svrnm Sep 6, 2022
8898778
fix: reset version of browser extension, add browser extension to rel…
svrnm Sep 6, 2022
41d96bf
Merge branch 'main' into bring-back-browser-extension
svrnm Sep 15, 2022
be3d49b
fix: resolve merge conflict
svrnm Sep 16, 2022
720786a
Merge branch 'open-telemetry:main' into bring-back-browser-extension
svrnm Sep 19, 2022
65da98f
Merge branch 'main' into bring-back-browser-extension
vmarchaud Sep 19, 2022
ed7f4b1
fix: update release please manifest
svrnm Sep 27, 2022
9c40889
Merge branch 'main' into bring-back-browser-extension
svrnm Sep 27, 2022
4cab851
fix: resolve merge conflict
svrnm Oct 7, 2022
004ebc3
Merge branch 'main' into bring-back-browser-extension
svrnm Oct 10, 2022
b89606e
Merge branch 'main' into bring-back-browser-extension
svrnm Oct 19, 2022
9aa97b1
fix: merge current release please manifest
svrnm Nov 9, 2022
82e0392
fix: bring back archived package.json to solve merge conflict (will b…
svrnm Nov 9, 2022
71787a2
Merge branch 'main' into bring-back-browser-extension
svrnm Nov 9, 2022
c64cbcd
fix: remove archived package.json
svrnm Nov 9, 2022
04dceec
Merge branch 'main' into bring-back-browser-extension
svrnm Nov 9, 2022
a0351e5
fix: update package.json
svrnm May 3, 2023
6118091
Merge branch 'main' into bring-back-browser-extension
svrnm May 3, 2023
bc73fc1
fix merge conflict and merge main
svrnm Jun 11, 2024
8006737
update component owners and release-please-config
svrnm Jun 11, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/component_owners.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ components:
- obecny
metapackages/auto-instrumentations-web:
- obecny
packages/opentelemetry-browser-extension-autoinjection:
- svrnm
packages/opentelemetry-host-metrics:
- legendecas
packages/opentelemetry-id-generator-aws-xray:
Expand Down
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"detectors/node/opentelemetry-resource-detector-alibaba-cloud":"0.27.2","detectors/node/opentelemetry-resource-detector-aws":"1.1.2","detectors/node/opentelemetry-resource-detector-gcp":"0.27.2","detectors/node/opentelemetry-resource-detector-github":"0.27.0","metapackages/auto-instrumentations-node":"0.32.0","metapackages/auto-instrumentations-web":"0.30.0","packages/opentelemetry-host-metrics":"0.30.0","packages/opentelemetry-id-generator-aws-xray":"1.1.0","packages/opentelemetry-test-utils":"0.32.0","plugins/node/instrumentation-amqplib":"0.31.0","plugins/node/instrumentation-fs":"0.5.0","plugins/node/instrumentation-tedious":"0.4.0","plugins/node/opentelemetry-instrumentation-aws-lambda":"0.33.0","plugins/node/opentelemetry-instrumentation-aws-sdk":"0.9.0","plugins/node/opentelemetry-instrumentation-bunyan":"0.30.0","plugins/node/opentelemetry-instrumentation-cassandra":"0.30.0","plugins/node/opentelemetry-instrumentation-connect":"0.30.0","plugins/node/opentelemetry-instrumentation-dns":"0.30.0","plugins/node/opentelemetry-instrumentation-express":"0.31.0","plugins/node/opentelemetry-instrumentation-generic-pool":"0.30.0","plugins/node/opentelemetry-instrumentation-graphql":"0.30.0","plugins/node/opentelemetry-instrumentation-hapi":"0.30.0","plugins/node/opentelemetry-instrumentation-ioredis":"0.32.0","plugins/node/opentelemetry-instrumentation-knex":"0.30.0","plugins/node/opentelemetry-instrumentation-koa":"0.32.0","plugins/node/instrumentation-lru-memoizer":"0.31.0","plugins/node/opentelemetry-instrumentation-memcached":"0.30.0","plugins/node/opentelemetry-instrumentation-mongodb":"0.32.0","plugins/node/opentelemetry-instrumentation-mysql":"0.31.0","plugins/node/opentelemetry-instrumentation-mysql2":"0.32.0","plugins/node/opentelemetry-instrumentation-nestjs-core":"0.31.0","plugins/node/opentelemetry-instrumentation-net":"0.30.0","plugins/node/opentelemetry-instrumentation-pg":"0.31.0","plugins/node/opentelemetry-instrumentation-pino":"0.31.0","plugins/node/opentelemetry-instrumentation-redis":"0.33.0","plugins/node/opentelemetry-instrumentation-redis-4":"0.32.0","plugins/node/opentelemetry-instrumentation-restify":"0.30.0","plugins/node/opentelemetry-instrumentation-router":"0.30.0","plugins/node/opentelemetry-instrumentation-winston":"0.30.0","plugins/web/opentelemetry-instrumentation-document-load":"0.30.0","plugins/web/opentelemetry-instrumentation-user-interaction":"0.31.0","plugins/web/opentelemetry-plugin-react-load":"0.28.0","propagators/opentelemetry-propagator-aws-xray":"1.1.0","propagators/opentelemetry-propagator-grpc-census-binary":"0.26.0","propagators/opentelemetry-propagator-instana":"0.2.0","propagators/opentelemetry-propagator-ot-trace":"0.26.1","plugins/node/opentelemetry-instrumentation-fastify":"0.29.0","packages/opentelemetry-propagation-utils":"0.28.0","plugins/web/opentelemetry-instrumentation-long-task":"0.31.0","detectors/node/opentelemetry-resource-detector-docker":"0.1.2","detectors/node/opentelemetry-resource-detector-instana":"0.3.0"}
{"detectors/node/opentelemetry-resource-detector-alibaba-cloud":"0.27.2","detectors/node/opentelemetry-resource-detector-aws":"1.1.2","detectors/node/opentelemetry-resource-detector-gcp":"0.27.2","detectors/node/opentelemetry-resource-detector-github":"0.27.0","metapackages/auto-instrumentations-node":"0.32.0","metapackages/auto-instrumentations-web":"0.30.0","packages/opentelemetry-host-metrics":"0.30.0","packages/opentelemetry-id-generator-aws-xray":"1.1.0","packages/opentelemetry-test-utils":"0.32.0","plugins/node/instrumentation-amqplib":"0.31.0","plugins/node/instrumentation-fs":"0.5.0","plugins/node/instrumentation-tedious":"0.4.0","plugins/node/opentelemetry-instrumentation-aws-lambda":"0.33.0","plugins/node/opentelemetry-instrumentation-aws-sdk":"0.9.0","plugins/node/opentelemetry-instrumentation-bunyan":"0.30.0","plugins/node/opentelemetry-instrumentation-cassandra":"0.30.0","plugins/node/opentelemetry-instrumentation-connect":"0.30.0","plugins/node/opentelemetry-instrumentation-dns":"0.30.0","plugins/node/opentelemetry-instrumentation-express":"0.31.0","plugins/node/opentelemetry-instrumentation-generic-pool":"0.30.0","plugins/node/opentelemetry-instrumentation-graphql":"0.30.0","plugins/node/opentelemetry-instrumentation-hapi":"0.30.0","plugins/node/opentelemetry-instrumentation-ioredis":"0.32.0","plugins/node/opentelemetry-instrumentation-knex":"0.30.0","plugins/node/opentelemetry-instrumentation-koa":"0.32.0","plugins/node/instrumentation-lru-memoizer":"0.31.0","plugins/node/opentelemetry-instrumentation-memcached":"0.30.0","plugins/node/opentelemetry-instrumentation-mongodb":"0.32.0","plugins/node/opentelemetry-instrumentation-mysql":"0.31.0","plugins/node/opentelemetry-instrumentation-mysql2":"0.32.0","plugins/node/opentelemetry-instrumentation-nestjs-core":"0.31.0","plugins/node/opentelemetry-instrumentation-net":"0.30.0","plugins/node/opentelemetry-instrumentation-pg":"0.31.0","plugins/node/opentelemetry-instrumentation-pino":"0.31.0","plugins/node/opentelemetry-instrumentation-redis":"0.33.0","plugins/node/opentelemetry-instrumentation-redis-4":"0.32.0","plugins/node/opentelemetry-instrumentation-restify":"0.30.0","plugins/node/opentelemetry-instrumentation-router":"0.30.0","plugins/node/opentelemetry-instrumentation-winston":"0.30.0","plugins/web/opentelemetry-instrumentation-document-load":"0.30.0","plugins/web/opentelemetry-instrumentation-user-interaction":"0.31.0","plugins/web/opentelemetry-plugin-react-load":"0.28.0","propagators/opentelemetry-propagator-aws-xray":"1.1.0","propagators/opentelemetry-propagator-grpc-census-binary":"0.26.0","propagators/opentelemetry-propagator-instana":"0.2.0","propagators/opentelemetry-propagator-ot-trace":"0.26.1","plugins/node/opentelemetry-instrumentation-fastify":"0.29.0","packages/opentelemetry-propagation-utils":"0.28.0","plugins/web/opentelemetry-instrumentation-long-task":"0.31.0","detectors/node/opentelemetry-resource-detector-docker":"0.1.2","detectors/node/opentelemetry-resource-detector-instana":"0.3.0","packages/opentelemetry-browser-extension-autoinjection":"0.29.0"}
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
# OpenTelemetry Browser Extension

## :warning: ARCHIVED PROJECT

> This project has been archived by the maintainers on August 3 2022 because it was causing a failure in the CI and does not have any maintainer.
> Anyone who would like to maintain this project should open a PR to move it back into the lerna project and add themselves to the component owners file.

This browser extension allows you to inject [OpenTelemetry](https://opentelemetry.io/) instrumentation in any web page. It uses the [Web SDK](https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-sdk-trace-web) and can export data to Zipkin or an OpenTelemetry Collector.

Compatible with OpenTelemetry JS API and SDK `1.0+`.
Expand All @@ -13,9 +8,9 @@ Compatible with OpenTelemetry JS API and SDK `1.0+`.

## Supported Environments

* Google Chrome (with [Manifest Version 3](https://developer.chrome.com/docs/extensions/mv3/intro/) support)
* Chromium (with Manifest Version 2)
* Firefox (*unstable*, with Manifest Version 2)
- Google Chrome (with [Manifest Version 3](https://developer.chrome.com/docs/extensions/mv3/intro/) support)
- Chromium (with Manifest Version 2)
- Firefox (_unstable_, with Manifest Version 2)

## Installation

Expand All @@ -32,9 +27,9 @@ npm run build

This will create a so-called unpacked extension into the `build/` folder you now can load into your browser:

* Open a new browser window and go to chrome://extensions
* Turn on "Developer Mode"
* Click on "Load unpacked" and select the `build/mv3` (or `build/mv2`) folder, which contains the extension
- Open a new browser window and go to chrome://extensions
- Turn on "Developer Mode"
- Click on "Load unpacked" and select the `build/mv3` (or `build/mv2`) folder, which contains the extension

If all goes well you should see the extension listed:

Expand All @@ -50,6 +45,16 @@ Click on `Save & Reload`, check the developer toolbar to see how spans being are

![This image shows spans being printed into the console of the developer toolbar for opentelemetry.io](./images/console.png)

### Usage with OTLP

If you'd like to export your telemetry to an OTLP endpoint (i.e. [collector](https://github.com/open-telemetry/opentelemetry-collector)) you might run into issues
with [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/) (CSP) and [Cross-Origin Resource Sharing](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) (CORS).

To work around CSP you need another browser extension, that allows you to disable CSP for your targeted website.

To work around CORS you need your OTLP endpoint to provide you with the right headers. To help you with that you find a `docker-compose.yml` in [./server] that
starts a nginx, OTel collector and jaeger instance for you. You can leverage that example to get your own installation up and running.

## Known Limitations

1. The extension works with [active tab](https://developer.chrome.com/docs/extensions/mv3/manifest/activeTab/) permission, this means that every time you want to use it, you have to click the extension icon at least once for your tab.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"precompile": "tsc --version && lerna run version:update --scope @opentelemetry/browser-extension-autoinjection --include-dependencies",
"prewatch": "npm run precompile",
"test": "nyc ts-mocha -p tsconfig.json 'test/**/*.test.ts'",
"version:update": "node ../../scripts/version-update.js",
"tdd": "npm run test -- --watch-extensions ts --watch",
"watch": "npx webpack --mode=development --watch",
"watch:mv2": "npx webpack --mode=development --watch --env MV=2",
Expand All @@ -26,60 +27,62 @@
"node": ">=8.12.0"
},
"peerDependencies": {
"@opentelemetry/api": "^1.0.0"
"@opentelemetry/api": "^1.2.0"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why upgrade the "@opentelemetry/api" minimum supported minor versions?

If the user is using an older version of the API, will it fail to work?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure why I changed it, it should work with 1.0 as well

},
"devDependencies": {
"@opentelemetry/api": "^1.0.0",
"@types/chrome": "0.0.154",
"@types/jsdom": "16.2.13",
"@opentelemetry/api": "^1.2.0",
"@types/chrome": "0.0.196",
"@types/jsdom": "16.2.15",
"@types/mocha": "8.2.3",
"@types/react": "17.0.16",
"@types/react-dom": "18.0.2",
"@types/sinon": "10.0.2",
"@types/sinon-chrome": "2.2.11",
"@typescript-eslint/eslint-plugin": "5.8.1",
"@typescript-eslint/parser": "5.8.1",
"@typescript-eslint/eslint-plugin": "5.36.1",
"@typescript-eslint/parser": "5.36.1",
"eslint": "8.7.0",
"eslint-config-airbnb-base": "15.0.0",
"eslint-plugin-header": "3.1.1",
"eslint-plugin-import": "2.25.4",
"eslint-plugin-import": "2.26.0",
"eslint-plugin-json5": "0.1.4",
"gts": "3.1.0",
"html-webpack-plugin": "5.3.2",
"html-webpack-plugin": "5.5.0",
"jimp": "0.16.1",
"jsdom": "15.2.1",
"jsdom": "16.7.0",
"mocha": "7.2.0",
"null-loader": "4.0.1",
"nyc": "15.1.0",
"responsive-loader": "2.3.0",
"responsive-loader": "3.1.1",
"rimraf": "3.0.2",
"sharp": "^0.30.7",
"sinon": "14.0.0",
"sinon-chrome": "3.0.1",
"ts-loader": "9.2.5",
"ts-mocha": "10.0.0",
"typescript": "4.3.5",
"webpack": "5.48.0",
"webpack-cli": "4.7.2",
"webpack": "5.74.0",
"webpack-cli": "4.10.0",
"webpack-merge": "5.8.0"
},
"dependencies": {
"@material-ui/core": "4.12.3",
"@material-ui/icons": "4.11.2",
"@material-ui/lab": "4.0.0-alpha.60",
"@material-ui/core": "4.12.4",
"@material-ui/icons": "4.11.3",
"@material-ui/lab": "4.0.0-alpha.61",
"@opentelemetry/context-zone": "^1.0.0",
"@opentelemetry/core": "^1.0.0",
"@opentelemetry/exporter-trace-otlp-http": "^0.29.2",
"@opentelemetry/exporter-trace-otlp-http": "^0.32.0",
"@opentelemetry/exporter-zipkin": "^1.0.0",
"@opentelemetry/instrumentation": "^0.29.2",
"@opentelemetry/instrumentation-document-load": "^0.29.0",
"@opentelemetry/instrumentation-fetch": "^0.29.2",
"@opentelemetry/instrumentation-xml-http-request": "^0.29.2",
"@opentelemetry/instrumentation": "^0.32.0",
"@opentelemetry/instrumentation-document-load": "^0.30.0",
"@opentelemetry/instrumentation-fetch": "^0.32.0",
"@opentelemetry/instrumentation-user-interaction": "^0.31.0",
"@opentelemetry/instrumentation-xml-http-request": "^0.32.0",
"@opentelemetry/resources": "^1.0.0",
"@opentelemetry/sdk-trace-base": "^1.0.0",
"@opentelemetry/sdk-trace-web": "^1.0.0",
"@opentelemetry/semantic-conventions": "^1.0.0",
"change-case": "4.1.2",
"json5": "2.2.0",
"json5": "2.2.1",
"react": "17.0.2",
"react-dom": "17.0.2"
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
server {
listen 80 default_server;
server_name _;
location / {
# Take care of preflight requests
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Max-Age' 1728000;
add_header "Access-Control-Allow-Origin" "$http_origin" always;
add_header 'Access-Control-Allow-Headers' 'Accept,Accept-Language,Content-Language,Content-Type,X-Requested-With' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}

add_header "Access-Control-Allow-Origin" "$http_origin" always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Access-Control-Allow-Headers' 'Accept,Accept-Language,Content-Language,Content-Type,X-Requested-With' always;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://collector:4318;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
version: "2"
services:
jaeger:
image: jaegertracing/all-in-one:latest
environment:
- COLLECTOR_OTLP_ENABLED=true
ports:
- "16686:16686"
proxy:
image: nginx:latest
ports:
- "4318:80"
volumes:
- ./default.conf:/etc/nginx/conf.d/default.conf
depends_on:
- collector
collector:
image: otel/opentelemetry-collector:latest
command: ["--config=/etc/otel-collector-config.yaml"]
volumes:
- ./otel-collector-config.yaml:/etc/otel-collector-config.yaml
depends_on:
- jaeger
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
receivers:
otlp:
protocols:
http:
include_metadata: true
processors:
resource:
attributes:
- key: browser.user_agent
from_context: User-Agent
action: upsert
attributes:
actions:
- key: http.client_ip
from_context: X-Forwarded-For
action: upsert

exporters:
otlp:
endpoint: jaeger:4317
tls:
insecure: true
insecure_skip_verify: true
logging:

service:
pipelines:
traces:
receivers: [otlp]
processors: [resource,attributes]
exporters: [logging, otlp]
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@ import { registerInstrumentations } from '@opentelemetry/instrumentation';
import { DocumentLoadInstrumentation } from '@opentelemetry/instrumentation-document-load';
import { FetchInstrumentation } from '@opentelemetry/instrumentation-fetch';
import { XMLHttpRequestInstrumentation } from '@opentelemetry/instrumentation-xml-http-request';
import { UserInteractionInstrumentation } from '@opentelemetry/instrumentation-user-interaction';
import { WebTracerProvider } from '@opentelemetry/sdk-trace-web';
import { ZoneContextManager } from '@opentelemetry/context-zone';
import { ZipkinExporter } from '@opentelemetry/exporter-zipkin';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
import { OTLPTraceExporter as OTLPHttpTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
import {
BatchSpanProcessor,
ConsoleSpanExporter,
Expand All @@ -37,45 +38,64 @@ export class WebInstrumentation {
withZoneContextManager: boolean;
provider: WebTracerProvider;
exporters: Exporters;
logger: Console;
instrumentations: {
[InstrumentationType.DOCUMENT_LOAD]: { enabled: boolean };
[InstrumentationType.FETCH]: { enabled: boolean };
[InstrumentationType.XML_HTTP_REQUEST]: { enabled: boolean };
[InstrumentationType.USER_INTERACTION]: { enabled: boolean };
};
constructor(
config: InstrumentationConfiguration,
provider: WebTracerProvider
provider: WebTracerProvider,
logger: Console
) {
this.exporters = config.exporters;
this.instrumentations = config.instrumentations;
this.provider = provider;
this.withZoneContextManager = config.withZoneContextManager;
this.logger = logger;
}

addExporters() {
if (this.exporters[ExporterType.CONSOLE].enabled) {
this.logger.info(
'[otel-extension] Logging spans to the console with ConsoleSpanExporter'
);
this.provider.addSpanProcessor(
new SimpleSpanProcessor(new ConsoleSpanExporter())
);
}

if (this.exporters[ExporterType.ZIPKIN].enabled) {
this.provider.addSpanProcessor(
new BatchSpanProcessor(
new ZipkinExporter({
const options = this.exporters[ExporterType.ZIPKIN].url
? {
url: this.exporters[ExporterType.ZIPKIN].url,
})
)
}
: {};
this.logger.info(
'[otel-extension] Logging spans to the console with ZipkinExporter(',
options,
')'
);
this.provider.addSpanProcessor(
new BatchSpanProcessor(new ZipkinExporter(options))
);
}

if (this.exporters[ExporterType.COLLECTOR_TRACE].enabled) {
if (this.exporters[ExporterType.TRACE_OTLP_HTTP].enabled) {
const options = this.exporters[ExporterType.TRACE_OTLP_HTTP].url
? {
url: this.exporters[ExporterType.TRACE_OTLP_HTTP].url,
}
: {};
this.logger.info(
'[otel-extension] Logging spans to the console with OTLPHttpTraceExporter(',
options,
')'
);
this.provider.addSpanProcessor(
new BatchSpanProcessor(
new OTLPTraceExporter({
url: this.exporters[ExporterType.COLLECTOR_TRACE].url,
})
)
new BatchSpanProcessor(new OTLPHttpTraceExporter(options))
);
}
}
Expand All @@ -95,6 +115,10 @@ export class WebInstrumentation {
instrumentations.push(new XMLHttpRequestInstrumentation());
}

if (this.instrumentations[InstrumentationType.USER_INTERACTION].enabled) {
instrumentations.push(new UserInteractionInstrumentation());
}

registerInstrumentations({
instrumentations,
tracerProvider: this.provider,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,16 @@ new WebInstrumentation(
[InstrumentationType.XML_HTTP_REQUEST]: {
enabled: true,
},
[InstrumentationType.USER_INTERACTION]: {
enabled: true,
},
},
withZoneContextManager: true,
},
new WebTracerProvider({
resource: new Resource({
[SemanticResourceAttributes.SERVICE_NAME]: window.location.hostname,
}),
})
}),
console
).register();
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@
"open_in_tab": true,
},
"web_accessible_resources": [
"instrumentation.js"
"instrumentation.js",
"instrumentation.js.map",
"contentScript.js.map",
"js/index.js.map"
],
"host_permissions": [
'<all_urls>'
]
}
}
Loading