diff --git a/.gitignore b/.gitignore index 24d92713..d5298543 100644 --- a/.gitignore +++ b/.gitignore @@ -1,51 +1,232 @@ +# Created by https://www.toptal.com/developers/gitignore/api/visualstudiocode,linux,windows,python +# Edit at https://www.toptal.com/developers/gitignore?templates=visualstudiocode,linux,windows,python + +### Linux ### +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +### Python ### # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] +*$py.class + # C extensions *.so + # Distribution / packaging .Python -env/ build/ develop-eggs/ dist/ downloads/ eggs/ +.eggs/ lib/ lib64/ parts/ sdist/ var/ +wheels/ +share/python-wheels/ *.egg-info/ .installed.cfg *.egg +MANIFEST + # PyInstaller # Usually these files are written by a python script from a template # before PyInstaller builds the exe, so as to inject date/other infos into it. *.manifest *.spec + # Installer logs pip-log.txt pip-delete-this-directory.txt + # Unit test / coverage reports htmlcov/ .tox/ +.nox/ .coverage +.coverage.* .cache nosetests.xml coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + # Translations *.mo *.pot + # Django stuff: *.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + # Sphinx documentation docs/_build/ + # PyBuilder +.pybuilder/ target/ -# User-specific files -*.suo -*.user -*.sln.docstates -.idea/ -doc/_build/ \ No newline at end of file + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/#use-with-ide +.pdm.toml + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ + +### VisualStudioCode ### +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +!.vscode/*.code-snippets + +# Local History for Visual Studio Code +.history/ + +# Built Visual Studio Code Extensions +*.vsix + +### VisualStudioCode Patch ### +# Ignore all local history of files +.history +.ionide + +# Support for Project snippet scope +.vscode/*.code-snippets + +# Ignore code-workspaces +*.code-workspace + +### Windows ### +# Windows thumbnail cache files +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +# End of https://www.toptal.com/developers/gitignore/api/visualstudiocode,linux,windows,python \ No newline at end of file diff --git a/.pylintrc b/.pylintrc new file mode 100644 index 00000000..bf56a306 --- /dev/null +++ b/.pylintrc @@ -0,0 +1,496 @@ +[MASTER] + +# A comma-separated list of package or module names from where C extensions may +# be loaded. Extensions are loading into the active Python interpreter and may +# run arbitrary code. +extension-pkg-whitelist= + +# Add list of files or directories to be excluded. They should be base names, not +# paths. +ignore=CVS,gen,proto + +# Add files or directories matching the regex patterns to be excluded. The +# regex matches against base names, not paths. +ignore-patterns= + +# Python code to execute, usually for sys.path manipulation such as +# pygtk.require(). +#init-hook= + +# Use multiple processes to speed up Pylint. Specifying 0 will auto-detect the +# number of processors available to use. +jobs=0 + +# Control the amount of potential inferred values when inferring a single +# object. This can help the performance when dealing with large functions or +# complex, nested conditions. +limit-inference-results=100 + +# List of plugins (as comma separated values of python modules names) to load, +# usually to register additional checkers. +load-plugins= + +# Pickle collected data for later comparisons. +persistent=yes + +# Specify a configuration file. +#rcfile= + +# When enabled, pylint would attempt to guess common misconfiguration and emit +# user-friendly hints instead of false-positive error messages. +suggestion-mode=yes + +# Allow loading of arbitrary C extensions. Extensions are imported into the +# active Python interpreter and may run arbitrary code. +unsafe-load-any-extension=no + + +[MESSAGES CONTROL] + +# Only show warnings with the listed confidence levels. Leave empty to show +# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED. +confidence= + +# Disable the message, report, category or checker with the given id(s). You +# can either give multiple identifiers separated by comma (,) or put this +# option multiple times (only on the command line, not in the configuration +# file where it should appear only once). You can also use "--disable=all" to +# disable everything first and then reenable specific checks. For example, if +# you want to run only the similarities checker, you can use "--disable=all +# --enable=similarities". If you want to run only the classes checker, but have +# no Warning level messages displayed, use "--disable=all --enable=classes +# --disable=W". +disable=missing-docstring, + fixme, # Warns about FIXME, TODO, etc. comments. + too-few-public-methods, # Might be good to re-enable this later. + too-many-instance-attributes, + too-many-arguments, + duplicate-code, + ungrouped-imports, # Leave this up to isort + wrong-import-order, # Leave this up to isort + bad-continuation, # Leave this up to black + line-too-long, # Leave this up to black + exec-used, + super-with-arguments, # temp-pylint-upgrade + isinstance-second-argument-not-valid-type, # temp-pylint-upgrade + raise-missing-from, # temp-pylint-upgrade + unused-argument, # temp-pylint-upgrade + redefined-builtin, + +# Enable the message, report, category or checker with the given id(s). You can +# either give multiple identifier separated by comma (,) or put this option +# multiple time (only on the command line, not in the configuration file where +# it should appear only once). See also the "--disable" option for examples. +# enable=c-extension-no-member + + +[REPORTS] + +# Python expression which should return a note less than 10 (10 is the highest +# note). You have access to the variables errors warning, statement which +# respectively contain the number of errors / warnings messages and the total +# number of statements analyzed. This is used by the global evaluation report +# (RP0004). +#evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) + +# Template used to display messages. This is a python new-style format string +# used to format the message information. See doc for all details. +#msg-template= + +# Set the output format. Available formats are text, parseable, colorized, json +# and msvs (visual studio). You can also give a reporter class, e.g. +# mypackage.mymodule.MyReporterClass. +#output-format=text + +# Tells whether to display a full report or only the messages. +#reports=no + +# Activate the evaluation score. +score=yes + + +[REFACTORING] + +# Maximum number of nested blocks for function / method body +max-nested-blocks=5 + +# Complete name of functions that never returns. When checking for +# inconsistent-return-statements if a never returning function is called then +# it will be considered as an explicit return statement and no message will be +# printed. +never-returning-functions=sys.exit + + +[LOGGING] + +# Format style used to check logging format string. `old` means using % +# formatting, while `new` is for `{}` formatting. +logging-format-style=old + +# Logging modules to check that the string format arguments are in logging +# function parameter format. +logging-modules=logging + + +[SPELLING] + +# Limits count of emitted suggestions for spelling mistakes. +max-spelling-suggestions=4 + +# Spelling dictionary name. Available dictionaries: none. To make it working +# install python-enchant package.. +spelling-dict= + +# List of comma separated words that should not be checked. +spelling-ignore-words= + +# A path to a file that contains private dictionary; one word per line. +spelling-private-dict-file= + +# Tells whether to store unknown words to indicated private dictionary in +# --spelling-private-dict-file option instead of raising a message. +spelling-store-unknown-words=no + + +[MISCELLANEOUS] + +# List of note tags to take in consideration, separated by a comma. +notes=FIXME, + XXX, + TODO + + +[TYPECHECK] + +# List of decorators that produce context managers, such as +# contextlib.contextmanager. Add to this list to register other decorators that +# produce valid context managers. +contextmanager-decorators=contextlib.contextmanager + +# List of members which are set dynamically and missed by pylint inference +# system, and so shouldn't trigger E1101 when accessed. Python regular +# expressions are accepted. +generated-members=zipkin_pb2.* + +# Tells whether missing members accessed in mixin class should be ignored. A +# mixin class is detected if its name ends with "mixin" (case insensitive). +#ignore-mixin-members=yes + +# Tells whether to warn about missing members when the owner of the attribute +# is inferred to be None. +#ignore-none=yes + +# This flag controls whether pylint should warn about no-member and similar +# checks whenever an opaque object is returned when inferring. The inference +# can return multiple potential results while evaluating a Python object, but +# some branches might not be evaluated, which results in partial inference. In +# that case, it might be useful to still emit no-member and other checks for +# the rest of the inferred objects. +#ignore-on-opaque-inference=yes + +# List of class names for which member attributes should not be checked (useful +# for classes with dynamically set attributes). This supports the use of +# qualified names. +ignored-classes=optparse.Values,thread._local,_thread._local + +# List of module names for which member attributes should not be checked +# (useful for modules/projects where namespaces are manipulated during runtime +# and thus existing member attributes cannot be deduced by static analysis. It +# supports qualified module names, as well as Unix pattern matching. +ignored-modules= + +# Show a hint with possible names when a member name was not found. The aspect +# of finding the hint is based on edit distance. +missing-member-hint=yes + +# The minimum edit distance a name should have in order to be considered a +# similar match for a missing member name. +missing-member-hint-distance=1 + +# The total number of similar names that should be taken in consideration when +# showing a hint for a missing member. +missing-member-max-choices=1 + + +[VARIABLES] + +# List of additional names supposed to be defined in builtins. Remember that +# you should avoid defining new builtins when possible. +additional-builtins= + +# Tells whether unused global variables should be treated as a violation. +allow-global-unused-variables=yes + +# List of strings which can identify a callback function by name. A callback +# name must start or end with one of those strings. +callbacks=cb_, + _cb + +# A regular expression matching the name of dummy variables (i.e. expected to +# not be used). +dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_ + +# Argument names that match this expression will be ignored. Default to name +# with leading underscore. +ignored-argument-names=_.*|^ignored_|^unused_|^kwargs|^args + +# Tells whether we should check for unused import in __init__ files. +init-import=no + +# List of qualified module names which can have objects that can redefine +# builtins. +redefining-builtins-modules=six.moves,past.builtins,future.builtins,builtins,io + + +[FORMAT] + +# Expected format of line ending, e.g. empty (any line ending), LF or CRLF. +# expected-line-ending-format=LF + +# Regexp for a line that is allowed to be longer than the limit. +ignore-long-lines=^\s*(# )??$ + +# Number of spaces of indent required inside a hanging or continued line. +indent-after-paren=4 + +# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 +# tab). +indent-string=' ' + +# Maximum number of characters on a single line. +max-line-length=79 + +# Maximum number of lines in a module. +max-module-lines=1000 + +# List of optional constructs for which whitespace checking is disabled. `dict- +# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}. +# `trailing-comma` allows a space between comma and closing bracket: (a, ). +# `empty-line` allows space-only lines. +no-space-check=trailing-comma, + dict-separator + +# Allow the body of a class to be on the same line as the declaration if body +# contains single statement. +single-line-class-stmt=no + +# Allow the body of an if to be on the same line as the test if there is no +# else. +single-line-if-stmt=no + + +[SIMILARITIES] + +# Ignore comments when computing similarities. +ignore-comments=yes + +# Ignore docstrings when computing similarities. +ignore-docstrings=yes + +# Ignore imports when computing similarities. +ignore-imports=no + +# Minimum lines number of a similarity. +min-similarity-lines=4 + + +[BASIC] + +# Naming style matching correct argument names. +argument-naming-style=snake_case + +# Regular expression matching correct argument names. Overrides argument- +# naming-style. +#argument-rgx= + +# Naming style matching correct attribute names. +attr-naming-style=snake_case + +# Regular expression matching correct attribute names. Overrides attr-naming- +# style. +#attr-rgx= + +# Bad variable names which should always be refused, separated by a comma. +bad-names=foo, + bar, + baz, + toto, + tutu, + tata + +# Naming style matching correct class attribute names. +class-attribute-naming-style=any + +# Regular expression matching correct class attribute names. Overrides class- +# attribute-naming-style. +#class-attribute-rgx= + +# Naming style matching correct class names. +class-naming-style=PascalCase + +# Regular expression matching correct class names. Overrides class-naming- +# style. +#class-rgx= + +# Naming style matching correct constant names. +const-naming-style=any + +# Regular expression matching correct constant names. Overrides const-naming- +# style. +#const-rgx= + +# Minimum line length for functions/classes that require docstrings, shorter +# ones are exempt. +docstring-min-length=-1 + +# Naming style matching correct function names. +function-naming-style=snake_case + +# Regular expression matching correct function names. Overrides function- +# naming-style. +#function-rgx= + +# Good variable names which should always be accepted, separated by a comma. +good-names=_, + log, + logger + +# Include a hint for the correct naming format with invalid-name. +include-naming-hint=yes + +# Naming style matching correct inline iteration names. +inlinevar-naming-style=any + +# Regular expression matching correct inline iteration names. Overrides +# inlinevar-naming-style. +#inlinevar-rgx= + +# Naming style matching correct method names. +method-naming-style=snake_case + +# Regular expression matching correct method names. Overrides method-naming- +# style. +#method-rgx= + +# Naming style matching correct module names. +module-naming-style=snake_case + +# Regular expression matching correct module names. Overrides module-naming- +# style. +#module-rgx= + +# Colon-delimited sets of names that determine each other's naming style when +# the name regexes allow several styles. +name-group= + +# Regular expression which should only match function or class names that do +# not require a docstring. +no-docstring-rgx=^_ + +# List of decorators that produce properties, such as abc.abstractproperty. Add +# to this list to register other decorators that produce valid properties. +# These decorators are taken in consideration only for invalid-name. +property-classes=abc.abstractproperty + +# Naming style matching correct variable names. +variable-naming-style=snake_case + +# Regular expression matching correct variable names. Overrides variable- +# naming-style. +variable-rgx=(([a-z_][a-z0-9_]{1,})|(_[a-z0-9_]*)|(__[a-z][a-z0-9_]+__))$ + + +[IMPORTS] + +# Allow wildcard imports from modules that define __all__. +allow-wildcard-with-all=no + +# Analyse import fallback blocks. This can be used to support both Python 2 and +# 3 compatible code, which means that the block might have code that exists +# only in one or another interpreter, leading to false positives when analysed. +analyse-fallback-blocks=yes + +# Deprecated modules which should not be used, separated by a comma. +deprecated-modules=optparse,tkinter.tix + +# Create a graph of external dependencies in the given file (report RP0402 must +# not be disabled). +ext-import-graph= + +# Create a graph of every (i.e. internal and external) dependencies in the +# given file (report RP0402 must not be disabled). +import-graph= + +# Create a graph of internal dependencies in the given file (report RP0402 must +# not be disabled). +int-import-graph= + +# Force import order to recognize a module as part of the standard +# compatibility libraries. +known-standard-library=six + +# Force import order to recognize a module as part of a third party library. +known-third-party=enchant + + +[CLASSES] + +# List of method names used to declare (i.e. assign) instance attributes. +defining-attr-methods=__init__, + __new__, + setUp + +# List of member names, which should be excluded from the protected access +# warning. +exclude-protected=_asdict, + _fields, + _replace, + _source, + _make, + _Span + +# List of valid names for the first argument in a class method. +valid-classmethod-first-arg=cls + +# List of valid names for the first argument in a metaclass class method. +valid-metaclass-classmethod-first-arg=cls + + +[DESIGN] + +# Maximum number of arguments for function / method. +max-args=5 + +# Maximum number of attributes for a class (see R0902). +max-attributes=7 + +# Maximum number of boolean expressions in an if statement. +max-bool-expr=5 + +# Maximum number of branch for function / method body. +max-branches=12 + +# Maximum number of locals for function / method body. +max-locals=15 + +# Maximum number of parents for a class (see R0901). +max-parents=7 + +# Maximum number of public methods for a class (see R0904). +max-public-methods=20 + +# Maximum number of return / yield for function / method body. +max-returns=6 + +# Maximum number of statements in function / method body. +max-statements=50 + +# Minimum number of public methods for a class (see R0903). +min-public-methods=2 + + +[EXCEPTIONS] + +# Exceptions that will emit a warning when being caught. Defaults to +# "Exception". +overgeneral-exceptions=Exception diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 21efd8af..00000000 --- a/.travis.yml +++ /dev/null @@ -1,20 +0,0 @@ -language: python -python: -- '2.7' -- '3.4' -- '3.5' -- '3.6' -script: -- pip install persist-queue -- python setup.py sdist -- python setup.py test -- django_tests/all_tests.sh -deploy: - provider: pypi - user: AppInsightsSDK - password: - secure: YisLTEfN9qhQzVg0FN2YJCl6dZ/3BsaW2/uzlP5St3sOJwEipOI3mUElvKrd58cha/L0qtWXxh9M3szJ3NT3DEx2K5Rysl/4yOWJPQ2/1P+dOyOXYPTm8RcJldSm2S65qjs2eWZrnyYTnj30ww8pbOuIZeI+U7RGDULGg0+0R9U= - distributions: "sdist bdist_wheel" - on: - tags: true - repo: Microsoft/ApplicationInsights-Python diff --git a/.vscode/settings.json b/.vscode/settings.json index 1384dfd4..2c92a7f9 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -14,5 +14,6 @@ "python.linting.flake8Enabled": false, "python.linting.pep8Enabled": true, "python.formatting.provider": "yapf", - "restructuredtext.confPath": "" + "restructuredtext.confPath": "", + "esbonio.sphinx.confDir": "" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 2715d2d3..63dc0302 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,47 +2,4 @@ ## Unreleased -TDB - -## 0.11.10 - -- Add deprecation notice to `README.rst` - -## 0.11.9 - -- Add `TelemetryProcessor` support. - -## 0.11.8 - -- Allow to specify and endpoint to upload telemetry to. -- Add option to set telemetry context for Flask integration. -- Add `async_` argument to `logging.enable` to use async telemetry channel. -- Add `endpoint` argument to `logging.enable` to configure custom telemetry endpoint. -- Fix Flask>=1.0 exception handler catching control-flow exceptions. -- Add `level` argument to `logging.enable` to configure telemetry verbosity. -- Add optional queue persistence to prevent telemetry loss in case of application crash. -- Add support for using `NullSender` with `AsynchronousQueue`. - -## 0.11.7 - -- Added `track_dependency`. -- Added optional `request_id` argument to `track_request`. - -## 0.11.6 - -- Fixed exception logging in Flask integration on Python 2. -- Fixed setting attributes in channel through context -- Added support for Cloud Role Name and Cloud Role Instance fields - -## 0.11.5 - -- Fixed setting custom properties through context. [#102](https://github.com/Microsoft/ApplicationInsights-Python/pull/102) - -## 0.11.4 - -- Schemas for all data types and context objects updated to the latest version. -- Add common properties argument to WSGIApplication initialization. Those common properties will be associated with telemetry produced by WSGIApplication. - -## 0.11.3 - -- Changelog started from this version. +- Initial commit \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 60e4d95a..afa1dc65 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,83 +1,30 @@ -# How to Contribute - -If you're interested in contributing, take a look at the general [contributor's -guide](https://github.com/Microsoft/ApplicationInsights-Home/blob/master/CONTRIBUTING.md) -first. - -This project is community supported and welcomes contributions. We are working -on plans to make it GA and officially support it. As part of GA we consider -[migrating -features](https://github.com/Microsoft/ApplicationInsights-Python/issues/105) of -this SDK to Open Census. Specifically things like automatic data collection and -more. - -## Build - -Run `python setup.py sdist` - -## Test - -- Unit tests: `python setup.py test` -- Django tests: `django_tests/all_tests.sh` - -Use `pip install -e ` to install it into test application for the testing purposes. - -## Generate documentation - -1. Install [sphinx](http://www.sphinx-doc.org/en/master/usage/installation.html). On Mac: `brew install sphinx-doc`. You can also use virtualenv: - ``` bash - % python3 -m venv env # Create 'env' directory - % . env/bin/activate # Activate virtual environment - % pip install sphinx django # Install sphinx and django (so sphinx can find it) - % python setup.py install # Install applicationinsights package - % cd doc - % make html - . - . - % deactivate # Exit virtualenv - ``` -2. Open docs folder `cd docs` -3. Generate html documents: `make html` -4. Update gh-pages branch - ``` bash - git clone https://github.com/Microsoft/ApplicationInsights-Python.git python-gh-pages - cd python-gh-pages/ - git checkout gh-pages - cp -r ../python/doc/build/html/ . - git add -A - git commit -m "upgrade to the latest version" - ``` - -## Releasing new version - -This is for repository maintainers only: - -This package is published to https://pypi.python.org/pypi/applicationinsights. These are the steps to publish the package. - -1. Merge `develop` to `master` via [pull request](https://github.com/Microsoft/ApplicationInsights-Python/compare/master...develop). -2. Tag `master`. Use [CHANGELOG.md](CHANGELOG.md) to get release description. -3. Travis should release a new version. For manual steps: - 1. Clean up repo: `git clean -xfd`. - 2. Make sure `wheel` is installed: `sudo pip install wheel`. - 3. Make sure `twine` is installed: `sudo pip install twine`. - 4. Create distributions `python setup.py bdist_wheel`. - 5. Create `~/.pypirc` file with the following content - ``` ini - [distutils] - index-servers= - pypi - - [pypi] - username:AppInsightsSDK - password= - ``` - 6. Test distributive. You can upload it to https://test.pypi.org/ using `twine upload --repository-url https://test.pypi.org/legacy/ dist/*` - 7. Upload the package `twine upload dist/*`. -4. Regenerate documentation on gh-pages branch. -5. Update versions in `TelemetryChannel.py`, `CHANGELOG.md`, `conf.py` and `setup.py`. +# Azure Monitor Contributing Guide + +TODO + +## Reporting Bugs/Feature Requests + +TODO ## Contributing +TODO + +## Development + +TODO + +## Documentation + +TODO + +## Licensing + +See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to +confirm the licensing of your contribution. + +## CLA + This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit @@ -87,6 +34,8 @@ When you submit a pull request, a CLA-bot will automatically determine whether y to provide a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repositories using our CLA. +## Code of Conduct + This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. \ No newline at end of file diff --git a/LICENSE.txt b/LICENSE similarity index 89% rename from LICENSE.txt rename to LICENSE index aa4eacd2..b2f52a2b 100644 --- a/LICENSE.txt +++ b/LICENSE @@ -1,6 +1,6 @@ -The MIT License (MIT) +Copyright (c) Microsoft Corporation. -Copyright (c) 2018 Microsoft +MIT License Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -12,11 +12,10 @@ furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index 6ac29b02..00000000 --- a/MANIFEST.in +++ /dev/null @@ -1,7 +0,0 @@ -include README.rst -include LICENSE.txt -include CHANGELOG.md -include CONTRIBUTING.md -# Include the test suite -recursive-include tests * -global-exclude *.pyc \ No newline at end of file diff --git a/README-deprecated.rst b/README-deprecated.rst deleted file mode 100644 index 61ed63f9..00000000 --- a/README-deprecated.rst +++ /dev/null @@ -1,429 +0,0 @@ -Application Insights for Python -=============================== - -.. image:: https://travis-ci.org/Microsoft/ApplicationInsights-Python.svg?branch=master - :target: https://travis-ci.org/Microsoft/ApplicationInsights-Python - -.. image:: https://badge.fury.io/py/applicationinsights.svg - :target: http://badge.fury.io/py/applicationinsights - - -This project extends the Application Insights API surface to support Python. -`Application Insights -`_ is a service that -allows developers to keep their application available, performing and -succeeding. This Python module will allow you to send telemetry of various kinds -(event, trace, exception, etc.) to the Application Insights service where they -can be visualized in the Azure Portal. A link to the Application Insights API -documentation can be found `here -`_. - -This project is not officially supported and not recommended for high load -production use. The project is open source and welcomes contributions. Please -refer to -`CONTRIBUTING.md `_ -for details. - -Requirements ------------- - -Python >=2.7 and Python >=3.4 are currently supported by this module. - -Installation ------------- - -To install the latest release you can use `pip `_. - -:: - - $ pip install applicationinsights - -Documentation -------------- - -Please see https://microsoft.github.io/ApplicationInsights-Python/ for full documentation. - -Usage ------ - -Once installed, you can send telemetry to Application Insights. Here are a few samples. - - **Note**: before you can send data to you will need an instrumentation key. Please see the `Getting an Application Insights Instrumentation Key `_ section for more information. - -**Sending a simple event telemetry item** - -.. code:: python - - from applicationinsights import TelemetryClient - tc = TelemetryClient('') - tc.track_event('Test event') - tc.flush() - -**Sending an event telemetry item with custom properties and measurements** - -.. code:: python - - from applicationinsights import TelemetryClient - tc = TelemetryClient('') - tc.track_event('Test event', { 'foo': 'bar' }, { 'baz': 42 }) - tc.flush() - -**Sending a trace telemetry item with custom properties** - -.. code:: python - - from applicationinsights import TelemetryClient - tc = TelemetryClient('') - tc.track_trace('Test trace', { 'foo': 'bar' }) - tc.flush() - -**Sending a metric telemetry item** - -.. code:: python - - from applicationinsights import TelemetryClient - tc = TelemetryClient('') - tc.track_metric('My Metric', 42) - tc.flush() - -**Sending an exception telemetry item with custom properties and measurements** - -.. code:: python - - import sys - from applicationinsights import TelemetryClient - tc = TelemetryClient('') - try: - raise Exception('blah') - except: - tc.track_exception() - - try: - raise Exception("blah") - except: - tc.track_exception(*sys.exc_info(), properties={ 'foo': 'bar' }, measurements={ 'x': 42 }) - tc.flush() - -**Configuring context for a telemetry client instance** - -.. code:: python - - from applicationinsights import TelemetryClient - tc = TelemetryClient('') - tc.context.application.ver = '1.2.3' - tc.context.device.id = 'My current device' - tc.context.device.oem_name = 'Asus' - tc.context.device.model = 'X31A' - tc.context.device.type = "Other" - tc.context.user.id = 'santa@northpole.net' - tc.context.properties['my_property'] = 'my_value' - tc.track_trace('My trace with context') - tc.flush() - -**Establishing correlation between telemetry objects** - -context field called operation_id can be set to associate telemetry items. -Since operation_id is being set as a property of telemetry client, the client shouldn't be reused in parallel threads as it might lead to concurrency issues. - -.. code:: python - - tc = TelemetryClient(instrumentation_key=instrumentation_key) - tc.context.operation.id = - tc.track_trace('Test trace') - tc.flush() - -**Configuring channel related properties** - -.. code:: python - - from applicationinsights import TelemetryClient - tc = TelemetryClient('') - # flush telemetry every 30 seconds (assuming we don't hit max_queue_item_count first) - tc.channel.sender.send_interval_in_milliseconds = 30 * 1000 - # flush telemetry if we have 10 or more telemetry items in our queue - tc.channel.queue.max_queue_length = 10 - -**Configuring TelemetryProcessor** - -.. code:: python - - from applicationinsights import TelemetryClient - def process(data, context): - data.properties["NEW_PROP"] = "MYPROP" # Add property - context.user.id = "MYID" # Change ID - return True # Not filtered - tc = TelemetryClient('') - tc.add_telemetry_processor(process) - -**Basic logging configuration (first option)** - -.. code:: python - - import logging - from applicationinsights.logging import enable - - # set up logging - enable('') - - # log something (this will be sent to the Application Insights service as a trace) - logging.info('This is a message') - - # logging shutdown will cause a flush of all un-sent telemetry items - logging.shutdown() - -**Basic logging configuration (second option)** - -.. code:: python - - import logging - from applicationinsights.logging import LoggingHandler - - # set up logging - handler = LoggingHandler('') - logging.basicConfig(handlers=[ handler ], format='%(levelname)s: %(message)s', level=logging.DEBUG) - - # log something (this will be sent to the Application Insights service as a trace) - logging.debug('This is a message') - - try: - raise Exception('Some exception') - except: - # this will send an exception to the Application Insights service - logging.exception('Code went boom!') - - # logging shutdown will cause a flush of all un-sent telemetry items - # alternatively flush manually via handler.flush() - logging.shutdown() - -**Advanced logging configuration** - -.. code:: python - - import logging - from applicationinsights import channel - from applicationinsights.logging import LoggingHandler - - # set up channel with context - telemetry_channel = channel.TelemetryChannel() - telemetry_channel.context.application.ver = '1.2.3' - telemetry_channel.context.properties['my_property'] = 'my_value' - - # set up logging - handler = LoggingHandler('', telemetry_channel=telemetry_channel) - handler.setLevel(logging.DEBUG) - handler.setFormatter(logging.Formatter('%(levelname)s: %(message)s')) - my_logger = logging.getLogger('simple_logger') - my_logger.setLevel(logging.DEBUG) - my_logger.addHandler(handler) - - # log something (this will be sent to the Application Insights service as a trace) - my_logger.debug('This is a message') - - # logging shutdown will cause a flush of all un-sent telemetry items - # alternatively flush manually via handler.flush() - logging.shutdown() - -**Logging unhandled exceptions** - -.. code:: python - - from applicationinsights.exceptions import enable - - # set up exception capture - enable('') - - # raise an exception (this will be sent to the Application Insights service as an exception telemetry object) - raise Exception('Boom!') - - # exceptions will cause a flush of all un-sent telemetry items - -**Logging unhandled exceptions with context** - -.. code:: python - - from applicationinsights import channel - from applicationinsights.exceptions import enable - - # set up channel with context - telemetry_channel = channel.TelemetryChannel() - telemetry_channel.context.application.ver = '1.2.3' - telemetry_channel.context.properties['my_property'] = 'my_value' - - # set up exception capture - enable('', telemetry_channel=telemetry_channel) - - # raise an exception (this will be sent to the Application Insights service as an exception telemetry object) - raise Exception('Boom!') - - # exceptions will cause a flush of all un-sent telemetry items - -**Integrating with Flask** - -.. code:: python - - from flask import Flask - from applicationinsights.flask.ext import AppInsights - - # instantiate the Flask application - app = Flask(__name__) - app.config['APPINSIGHTS_INSTRUMENTATIONKEY'] = '' - - # log requests, traces and exceptions to the Application Insights service - appinsights = AppInsights(app) - - # define a simple route - @app.route('/') - def hello_world(): - # the following message will be sent to the Flask log as well as Application Insights - app.logger.info('Hello World route was called') - - return 'Hello World!' - - # run the application - if __name__ == '__main__': - app.run() - -**Integrating with Django** - -Place the following in your `settings.py` file: - -.. code:: python - - # If on Django < 1.10 - MIDDLEWARE_CLASSES = [ - # ... or whatever is below for you ... - 'django.middleware.security.SecurityMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.middleware.common.CommonMiddleware', - 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', - 'django.middleware.clickjacking.XFrameOptionsMiddleware', - # ... or whatever is above for you ... - 'applicationinsights.django.ApplicationInsightsMiddleware', # Add this middleware to the end - ] - - # If on Django >= 1.10 - MIDDLEWARE = [ - # ... or whatever is below for you ... - 'django.middleware.security.SecurityMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.middleware.common.CommonMiddleware', - 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', - 'django.middleware.clickjacking.XFrameOptionsMiddleware', - # ... or whatever is above for you ... - 'applicationinsights.django.ApplicationInsightsMiddleware', # Add this middleware to the end - ] - - APPLICATION_INSIGHTS = { - # (required) Your Application Insights instrumentation key - 'ikey': "00000000-0000-0000-0000-000000000000", - - # (optional) By default, request names are logged as the request method - # and relative path of the URL. To log the fully-qualified view names - # instead, set this to True. Defaults to False. - 'use_view_name': True, - - # (optional) To log arguments passed into the views as custom properties, - # set this to True. Defaults to False. - 'record_view_arguments': True, - - # (optional) Exceptions are logged by default, to disable, set this to False. - 'log_exceptions': False, - - # (optional) Events are submitted to Application Insights asynchronously. - # send_interval specifies how often the queue is checked for items to submit. - # send_time specifies how long the sender waits for new input before recycling - # the background thread. - 'send_interval': 1.0, # Check every second - 'send_time': 3.0, # Wait up to 3 seconds for an event - - # (optional, uncommon) If you must send to an endpoint other than the - # default endpoint, specify it here: - 'endpoint': "https://dc.services.visualstudio.com/v2/track", - } - -This will log all requests and exceptions to the instrumentation key -specified in the `APPLICATION_INSIGHTS` setting. In addition, an -`appinsights` property will be placed on each incoming `request` object in -your views. This will have the following properties: - -* `client`: This is an instance of the `applicationinsights.TelemetryClient` - type, which will submit telemetry to the same instrumentation key, and - will parent each telemetry item to the current request. -* `request`: This is the `applicationinsights.channel.contracts.RequestData` - instance for the current request. You can modify properties on this - object during the handling of the current request. It will be submitted - when the request has finished. -* `context`: This is the `applicationinsights.channel.TelemetryContext` - object for the current ApplicationInsights sender. - -You can also hook up logging to Django. For example, to log all builtin -Django warnings and errors, use the following logging configuration in -`settings.py`: - -.. code:: python - - LOGGING = { - 'version': 1, - 'disable_existing_loggers': False, - 'handlers': { - # The application insights handler is here - 'appinsights': { - 'class': 'applicationinsights.django.LoggingHandler', - 'level': 'WARNING' - } - }, - 'loggers': { - 'django': { - 'handlers': ['appinsights'], - 'level': 'WARNING', - 'propagate': True, - } - } - } - -See Django's `logging documentation `_ -for more information. - -**Integrating with other web frameworks** - -For any other Python web framework that is `WSGI compliant `_, -the `WSGIApplication `_ -can be used as a middleware to log requests to Application Insights. - -Add common properties to WSGIApplication request events by passing in a dictionary to the WSGIApplication constructor: - -.. code:: python - - from wsgiref.simple_server import make_server - from pyramid.config import Configurator - from pyramid.response import Response - from applicationinsights.requests import WSGIApplication - - # define a simple pyramid route - def hello_world(request): - return Response('Hello World!') - - # construct dictionary which contains properties to be included with every request event - common_properties = { - "service": "hello_world_flask_app", - "environment": "production" - } - - if __name__ == '__main__': - # create a simple pyramid app - with Configurator() as config: - config.add_route('hello', '/') - config.add_view(hello_world, route_name='hello') - app = config.make_wsgi_app() - - # wrap the app in the application insights request logging middleware - app = WSGIApplication('', app, common_properties=common_properties) - - # run the app - server = make_server('0.0.0.0', 6543, app) - server.serve_forever() diff --git a/README.md b/README.md new file mode 100644 index 00000000..93022db5 --- /dev/null +++ b/README.md @@ -0,0 +1,34 @@ +# Azure Monitor Opentelemetry Distro + +Azure Monitor Distro of [Opentelemetry Python][opentelemetry-python] provides multiple installable components available for an Opentelemetry Azure Monitor monitoring solution. It allows you to instrument your Python applications to capture and report telemetry to Azure Monitor via the Azure monitor exporters. + +This distro automatically installs the following libraries: + +* [Azure Monitor OpenTelemetry exporters][azure_monitor_opentelemetry_exporters] + +## Getting started + +### Install the package + +Install the Azure Monitor Opentelemetry Distro with [pip][pip]: + +```Bash +pip install azure-monitor-opentelemetry-distro --pre +``` + +### Prerequisites: +To use this package, you must have: +* Azure subscription - [Create a free account][azure_sub] +* Azure Monitor - [How to use application insights][application_insights_namespace] +* Opentelemetry SDK - [Opentelemtry SDK for Python][ot_sdk_python] +* Python 3.6 or later - [Install Python][python] + +### Additional documentation + +[Azure Portal][azure_portal] + + +[azure_monitor_opentelemetry_exporters]: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/monitor/azure-monitor-opentelemetry-exporter#microsoft-opentelemetry-exporter-for-azure-monitor +[azure_portal]: https://portal.azure.com +[pip]: https://pypi.org/project/pip/ +[opentelemetry-python]: https://github.com/open-telemetry/opentelemetry-python diff --git a/README.rst b/README.rst deleted file mode 100644 index c8f18137..00000000 --- a/README.rst +++ /dev/null @@ -1,3 +0,0 @@ -This SDK is no longer maintained or supported by Microsoft. Check out the `Python Open Census SDK `_ for Azure Monitor's latest Python investments. Azure Monitor only provides support when using the `supported SDKs -`_. We’re constantly assessing opportunities to expand our support for other languages, so follow our `GitHub Announcements -`_ page to receive the latest SDK news. diff --git a/Schema/PublicSchema/AvailabilityData.bond b/Schema/PublicSchema/AvailabilityData.bond deleted file mode 100644 index ab6d0834..00000000 --- a/Schema/PublicSchema/AvailabilityData.bond +++ /dev/null @@ -1,47 +0,0 @@ -import "Domain.bond" - -namespace AI - -[Description("Instances of AvailabilityData represent the result of executing an availability test.")] -struct AvailabilityData - : Domain -{ - [Description("Schema version")] - 10: required int32 ver = 2; - - [MaxStringLength("64")] - [Description("Identifier of a test run. Use it to correlate steps of test run and telemetry generated by the service.")] - [ActAsRequired("Renaming testRunId to id.")] - 21: required string id; - - [MaxStringLength("1024")] - [Description("Name of the test that these availability results represent.")] - [ActAsRequired("Renaming testName to name.")] - 41: required string name; - - [Description("Duration in format: DD.HH:MM:SS.MMMMMM. Must be less than 1000 days.")] - [CSType("TimeSpan")] - 50: required string duration; - - [ActAsRequired("Renaming result to success.")] - [Description("Success flag.")] - 61: required bool success; - - [MaxStringLength("1024")] - [Description("Name of the location where the test was run from.")] - 70: string runLocation; - - [MaxStringLength("8192")] - [Description("Diagnostic message for the result.")] - 80: string message; - - [Description("Collection of custom properties.")] - [MaxKeyLength("150")] - [MaxValueLength("8192")] - 100: map properties; - - [Description("Collection of custom measurements.")] - [MaxKeyLength("150")] - 200: map measurements; - -} diff --git a/Schema/PublicSchema/Base.bond b/Schema/PublicSchema/Base.bond deleted file mode 100644 index 0555316c..00000000 --- a/Schema/PublicSchema/Base.bond +++ /dev/null @@ -1,11 +0,0 @@ - -namespace AI - -[Description("Data struct to contain only C section with custom fields.")] -struct Base -{ - [Name("ItemTypeName")] - [Description("Name of item (B section) if any. If telemetry data is derived straight from this, this should be null.")] - 10: string baseType; - -} diff --git a/Schema/PublicSchema/ContextTagKeys.bond b/Schema/PublicSchema/ContextTagKeys.bond deleted file mode 100644 index 0a493716..00000000 --- a/Schema/PublicSchema/ContextTagKeys.bond +++ /dev/null @@ -1,101 +0,0 @@ - -namespace AI - -[ContextContract("Emit")] -[PseudoType("JSMap")] -struct ContextTagKeys -{ - [Description("Application version. Information in the application context fields is always about the application that is sending the telemetry.")] - [MaxStringLength("1024")] - 10: string ApplicationVersion = "ai.application.ver"; - - [Description("Unique client device id. Computer name in most cases.")] - [MaxStringLength("1024")] - 100: string DeviceId = "ai.device.id"; - - [Description("Device locale using - pattern, following RFC 5646. Example 'en-US'.")] - [MaxStringLength("64")] - 115: string DeviceLocale = "ai.device.locale"; - - [Description("Model of the device the end user of the application is using. Used for client scenarios. If this field is empty then it is derived from the user agent.")] - [MaxStringLength("256")] - 120: string DeviceModel = "ai.device.model"; - - [Description("Client device OEM name taken from the browser.")] - [MaxStringLength("256")] - 130: string DeviceOEMName = "ai.device.oemName"; - - [Description("Operating system name and version of the device the end user of the application is using. If this field is empty then it is derived from the user agent. Example 'Windows 10 Pro 10.0.10586.0'")] - [MaxStringLength("256")] - 140: string DeviceOSVersion = "ai.device.osVersion"; - - [Description("The type of the device the end user of the application is using. Used primarily to distinguish JavaScript telemetry from server side telemetry. Examples: 'PC', 'Phone', 'Browser'. 'PC' is the default value.")] - [MaxStringLength("64")] - 160: string DeviceType = "ai.device.type"; - - [Description("The IP address of the client device. IPv4 and IPv6 are supported. Information in the location context fields is always about the end user. When telemetry is sent from a service, the location context is about the user that initiated the operation in the service.")] - [MaxStringLength("46")] - 200: string LocationIp = "ai.location.ip"; - - [Description("A unique identifier for the operation instance. The operation.id is created by either a request or a page view. All other telemetry sets this to the value for the containing request or page view. Operation.id is used for finding all the telemetry items for a specific operation instance.")] - [MaxStringLength("128")] - 300: string OperationId = "ai.operation.id"; - - [Description("The name (group) of the operation. The operation.name is created by either a request or a page view. All other telemetry items set this to the value for the containing request or page view. Operation.name is used for finding all the telemetry items for a group of operations (i.e. 'GET Home/Index').")] - [MaxStringLength("1024")] - 305: string OperationName = "ai.operation.name"; - - [Description("The unique identifier of the telemetry item's immediate parent.")] - [MaxStringLength("128")] - 310: string OperationParentId = "ai.operation.parentId"; - - [Description("Name of synthetic source. Some telemetry from the application may represent a synthetic traffic. It may be web crawler indexing the web site, site availability tests or traces from diagnostic libraries like Application Insights SDK itself.")] - [MaxStringLength("1024")] - 320: string OperationSyntheticSource = "ai.operation.syntheticSource"; - - [Description("The correlation vector is a light weight vector clock which can be used to identify and order related events across clients and services.")] - [MaxStringLength("64")] - 330: string OperationCorrelationVector = "ai.operation.correlationVector"; - - [Description("Session ID - the instance of the user's interaction with the app. Information in the session context fields is always about the end user. When telemetry is sent from a service, the session context is about the user that initiated the operation in the service.")] - [MaxStringLength("64")] - 400: string SessionId = "ai.session.id"; - - [Description("Boolean value indicating whether the session identified by ai.session.id is first for the user or not.")] - [MaxStringLength("5")] - [Question("Should it be marked as JSType-bool for breeze?")] - 405: string SessionIsFirst = "ai.session.isFirst"; - - [Description("In multi-tenant applications this is the account ID or name which the user is acting with. Examples may be subscription ID for Azure portal or blog name blogging platform.")] - [MaxStringLength("1024")] - 505: string UserAccountId = "ai.user.accountId"; - - [Description("Anonymous user id. Represents the end user of the application. When telemetry is sent from a service, the user context is about the user that initiated the operation in the service.")] - [MaxStringLength("128")] - 515: string UserId = "ai.user.id"; - - [Description("Authenticated user id. The opposite of ai.user.id, this represents the user with a friendly name. Since it's PII information it is not collected by default by most SDKs.")] - [MaxStringLength("1024")] - 525: string UserAuthUserId = "ai.user.authUserId"; - - [Description("Name of the role the application is a part of. Maps directly to the role name in azure.")] - [MaxStringLength("256")] - 705: string CloudRole = "ai.cloud.role"; - - [Description("Name of the instance where the application is running. Computer name for on-premisis, instance name for Azure.")] - [MaxStringLength("256")] - 715: string CloudRoleInstance = "ai.cloud.roleInstance"; - - [Description("SDK version. See https://github.com/Microsoft/ApplicationInsights-Home/blob/master/SDK-AUTHORING.md#sdk-version-specification for information.")] - [MaxStringLength("64")] - 1000: string InternalSdkVersion = "ai.internal.sdkVersion"; - - [Description("Agent version. Used to indicate the version of StatusMonitor installed on the computer if it is used for data collection.")] - [MaxStringLength("64")] - 1001: string InternalAgentVersion = "ai.internal.agentVersion"; - - [Description("This is the node name used for billing purposes. Use it to override the standard detection of nodes.")] - [MaxStringLength("256")] - 1002: string InternalNodeName = "ai.internal.nodeName"; - -} diff --git a/Schema/PublicSchema/Data.bond b/Schema/PublicSchema/Data.bond deleted file mode 100644 index def8b38d..00000000 --- a/Schema/PublicSchema/Data.bond +++ /dev/null @@ -1,13 +0,0 @@ -import "Base.bond" - -namespace AI - -[Description("Data struct to contain both B and C sections.")] -struct Data - : Base -{ - [Name("Item")] - [Description("Container for data item (B section).")] - 20: required TDomain baseData; - -} diff --git a/Schema/PublicSchema/DataPoint.bond b/Schema/PublicSchema/DataPoint.bond deleted file mode 100644 index 053a61f4..00000000 --- a/Schema/PublicSchema/DataPoint.bond +++ /dev/null @@ -1,34 +0,0 @@ -import "DataPointType.bond" - -namespace AI - -[Description("Metric data single measurement.")] -struct DataPoint -{ - [Description("Namespace of the metric.")] - [MaxStringLength("256")] - 5: string ns; - - [Description("Name of the metric.")] - [MaxStringLength("1024")] - 10: required string name; - - [Description("Metric type. Single measurement or the aggregated value.")] - 20: AI.DataPointType kind = Measurement; - - [Description("Single value for measurement. Sum of individual measurements for the aggregation.")] - 30: required double value; - - [Description("Metric weight of the aggregated metric. Should not be set for a measurement.")] - 40: nullable count; - - [Description("Minimum value of the aggregated metric. Should not be set for a measurement.")] - 50: nullable min; - - [Description("Maximum value of the aggregated metric. Should not be set for a measurement.")] - 60: nullable max; - - [Description("Standard deviation of the aggregated metric. Should not be set for a measurement.")] - 70: nullable stdDev; - -} diff --git a/Schema/PublicSchema/DataPointType.bond b/Schema/PublicSchema/DataPointType.bond deleted file mode 100644 index a65c6fc6..00000000 --- a/Schema/PublicSchema/DataPointType.bond +++ /dev/null @@ -1,8 +0,0 @@ -namespace AI - -[Description("Type of the metric data measurement.")] -enum DataPointType -{ - Measurement, - Aggregation, -} diff --git a/Schema/PublicSchema/Domain.bond b/Schema/PublicSchema/Domain.bond deleted file mode 100644 index 4ad84d3b..00000000 --- a/Schema/PublicSchema/Domain.bond +++ /dev/null @@ -1,7 +0,0 @@ - -namespace AI - -[Description("The abstract common base of all domains.")] -struct Domain -{ -} diff --git a/Schema/PublicSchema/Envelope.bond b/Schema/PublicSchema/Envelope.bond deleted file mode 100644 index 3dba5e2b..00000000 --- a/Schema/PublicSchema/Envelope.bond +++ /dev/null @@ -1,50 +0,0 @@ -import "Base.bond" - -namespace AI - -[Description("System variables for a telemetry item.")] -struct Envelope -{ - [Description("Envelope version. For internal use only. By assigning this the default, it will not be serialized within the payload unless changed to a value other than #1.")] - [Name("SchemaVersion")] - 10: int32 ver = 1; - - [Description("Type name of telemetry data item.")] - [Name("DataTypeName")] - [MaxStringLength("1024")] - 20: required string name; - - [Description("Event date time when telemetry item was created. This is the wall clock time on the client when the event was generated. There is no guarantee that the client's time is accurate. This field must be formatted in UTC ISO 8601 format, with a trailing 'Z' character, as described publicly on https://en.wikipedia.org/wiki/ISO_8601#UTC. Note: the number of decimal seconds digits provided are variable (and unspecified). Consumers should handle this, i.e. managed code consumers should not use format 'O' for parsing as it specifies a fixed length. Example: 2009-06-15T13:45:30.0000000Z.")] - [Name("DateTime")] - [CSType("DateTimeOffset")] - [JSType("Date")] - [HockeyAppMinDateOffsetFromNow("2592000000")] - [MinDateOffsetFromNow("172800000")] - [MaxDateOffsetFromNow("7200000")] - [MaxStringLength("64")] - 30: required string time; - - [Name("SamplingRate")] - [Description("Sampling rate used in application. This telemetry item represents 1 / sampleRate actual telemetry items.")] - 40: double sampleRate = 100.0; - - [Description("Sequence field used to track absolute order of uploaded events.")] - [Name("SequenceNumber")] - [MaxStringLength("64")] - 50: string seq; - - [Description("The application's instrumentation key. The key is typically represented as a GUID, but there are cases when it is not a guid. No code should rely on iKey being a GUID. Instrumentation key is case insensitive.")] - [Name("InstrumentationKey")] - [MaxStringLength("40")] - 60: string iKey; - - [Name("Tags")] - [TypeAlias("ContextTagKeys")] - [Description("Key/value collection of context properties. See ContextTagKeys for information on available properties.")] - 500: map tags; - - [Name("TelemetryData")] - [Description("Telemetry data item.")] - 999: Base data; - -} diff --git a/Schema/PublicSchema/EventData.bond b/Schema/PublicSchema/EventData.bond deleted file mode 100644 index 77a538cb..00000000 --- a/Schema/PublicSchema/EventData.bond +++ /dev/null @@ -1,26 +0,0 @@ -import "Domain.bond" - -namespace AI - -[Description("Instances of Event represent structured event records that can be grouped and searched by their properties. Event data item also creates a metric of event count by name.")] -struct EventData - : Domain -{ - [Description("Schema version")] - 10: required int32 ver = 2; - - [MaxStringLength("512")] - [Description("Event name. Keep it low cardinality to allow proper grouping and useful metrics.")] - [Question("Why Custom Event name is shorter than Request name or dependency name?")] - 20: required string name; - - [Description("Collection of custom properties.")] - [MaxKeyLength("150")] - [MaxValueLength("8192")] - 100: map properties; - - [Description("Collection of custom measurements.")] - [MaxKeyLength("150")] - 200: map measurements; - -} diff --git a/Schema/PublicSchema/ExceptionData.bond b/Schema/PublicSchema/ExceptionData.bond deleted file mode 100644 index 75685fa3..00000000 --- a/Schema/PublicSchema/ExceptionData.bond +++ /dev/null @@ -1,33 +0,0 @@ -import "Domain.bond" -import "ExceptionDetails.bond" -import "SeverityLevel.bond" - -namespace AI - -[Description("An instance of Exception represents a handled or unhandled exception that occurred during execution of the monitored application.")] -struct ExceptionData - : Domain -{ - [Description("Schema version")] - 10: required int32 ver = 2; - - [Description("Exception chain - list of inner exceptions.")] - 50: required vector exceptions; - - [Description("Severity level. Mostly used to indicate exception severity level when it is reported by logging library.")] - 60: nullable severityLevel; - - [Description("Identifier of where the exception was thrown in code. Used for exceptions grouping. Typically a combination of exception type and a function from the call stack.")] - [MaxStringLength("1024")] - 80: string problemId; - - [Description("Collection of custom properties.")] - [MaxKeyLength("150")] - [MaxValueLength("8192")] - 100: map properties; - - [Description("Collection of custom measurements.")] - [MaxKeyLength("150")] - 200: map measurements; - -} diff --git a/Schema/PublicSchema/ExceptionDetails.bond b/Schema/PublicSchema/ExceptionDetails.bond deleted file mode 100644 index e3327086..00000000 --- a/Schema/PublicSchema/ExceptionDetails.bond +++ /dev/null @@ -1,32 +0,0 @@ -import "StackFrame.bond" - -namespace AI - -[Description("Exception details of the exception in a chain.")] -struct ExceptionDetails -{ - [Description("In case exception is nested (outer exception contains inner one), the id and outerId properties are used to represent the nesting.")] - 10: int32 id; - - [Description("The value of outerId is a reference to an element in ExceptionDetails that represents the outer exception")] - 20: int32 outerId; - - [Description("Exception type name.")] - [MaxStringLength("1024")] - 30: required string typeName; - - [Description("Exception message.")] - [MaxStringLength("32768")] - 40: required string message; - - [Description("Indicates if full exception stack is provided in the exception. The stack may be trimmed, such as in the case of a StackOverflow exception.")] - 50: bool hasFullStack = true; - - [Description("Text describing the stack. Either stack or parsedStack should have a value.")] - [MaxStringLength("32768")] - 60: string stack; - - [Description("List of stack frames. Either stack or parsedStack should have a value.")] - 70: vector parsedStack; - -} diff --git a/Schema/PublicSchema/MessageData.bond b/Schema/PublicSchema/MessageData.bond deleted file mode 100644 index c6022ac0..00000000 --- a/Schema/PublicSchema/MessageData.bond +++ /dev/null @@ -1,25 +0,0 @@ -import "Domain.bond" -import "SeverityLevel.bond" - -namespace AI - -[Description("Instances of Message represent printf-like trace statements that are text-searched. Log4Net, NLog and other text-based log file entries are translated into intances of this type. The message does not have measurements.")] -struct MessageData - : Domain -{ - [Description("Schema version")] - 10: required int32 ver = 2; - - [MaxStringLength("32768")] - [Description("Trace message")] - 20: required string message; - - [Description("Trace severity level.")] - 30: nullable severityLevel; - - [Description("Collection of custom properties.")] - [MaxKeyLength("150")] - [MaxValueLength("8192")] - 100: map properties; - -} diff --git a/Schema/PublicSchema/MetricData.bond b/Schema/PublicSchema/MetricData.bond deleted file mode 100644 index a49f8e9f..00000000 --- a/Schema/PublicSchema/MetricData.bond +++ /dev/null @@ -1,21 +0,0 @@ -import "Domain.bond" -import "DataPoint.bond" - -namespace AI - -[Description("An instance of the Metric item is a list of measurements (single data points) and/or aggregations.")] -struct MetricData - : Domain -{ - [Description("Schema version")] - 10: required int32 ver = 2; - - [Description("List of metrics. Only one metric in the list is currently supported by Application Insights storage. If multiple data points were sent only the first one will be used.")] - 20: required vector metrics; - - [Description("Collection of custom properties.")] - [MaxKeyLength("150")] - [MaxValueLength("8192")] - 100: map properties; - -} diff --git a/Schema/PublicSchema/PageViewData.bond b/Schema/PublicSchema/PageViewData.bond deleted file mode 100644 index 5df9fb06..00000000 --- a/Schema/PublicSchema/PageViewData.bond +++ /dev/null @@ -1,25 +0,0 @@ -import "EventData.bond" - -namespace AI - -[Description("An instance of PageView represents a generic action on a page like a button click. It is also the base type for PageView.")] -[Alias("PageviewData;PageEventData")] -struct PageViewData - : EventData -{ - [MaxStringLength("2048")] - [Description("Request URL with all query string parameters")] - 10: string url; - - [CSType("TimeSpan")] - [Description("Request duration in format: DD.HH:MM:SS.MMMMMM. For a page view (PageViewData), this is the duration. For a page view with performance information (PageViewPerfData), this is the page load time. Must be less than 1000 days.")] - 20: string duration; - - [MaxStringLength("128")] - [Description("Identifier of a page view instance. Used for correlation between page view and other telemetry items.")] - 50: string id; - - [MaxStringLength("2048")] - [Description("Fully qualified page URI or URL of the referring page; if unknown, leave blank.")] - 60: string referrerUri; -} diff --git a/Schema/PublicSchema/PageViewPerfData.bond b/Schema/PublicSchema/PageViewPerfData.bond deleted file mode 100644 index b35eab1f..00000000 --- a/Schema/PublicSchema/PageViewPerfData.bond +++ /dev/null @@ -1,30 +0,0 @@ -import "PageViewData.bond" - -namespace AI - -[Description("An instance of PageViewPerf represents: a page view with no performance data, a page view with performance data, or just the performance data of an earlier page request.")] -[Alias("PageViewPerformanceData;PageviewPerformanceData")] -struct PageViewPerfData - : PageViewData -{ - [Description("Performance total in TimeSpan 'G' (general long) format: d:hh:mm:ss.fffffff")] - [CSType("TimeSpan")] - 10: string perfTotal; - - [Description("Network connection time in TimeSpan 'G' (general long) format: d:hh:mm:ss.fffffff")] - [CSType("TimeSpan")] - 20: string networkConnect; - - [Description("Sent request time in TimeSpan 'G' (general long) format: d:hh:mm:ss.fffffff")] - [CSType("TimeSpan")] - 30: string sentRequest; - - [Description("Received response time in TimeSpan 'G' (general long) format: d:hh:mm:ss.fffffff")] - [CSType("TimeSpan")] - 40: string receivedResponse; - - [Description("DOM processing time in TimeSpan 'G' (general long) format: d:hh:mm:ss.fffffff")] - [CSType("TimeSpan")] - 50: string domProcessing; - -} diff --git a/Schema/PublicSchema/RemoteDependencyData.bond b/Schema/PublicSchema/RemoteDependencyData.bond deleted file mode 100644 index 6b3ab748..00000000 --- a/Schema/PublicSchema/RemoteDependencyData.bond +++ /dev/null @@ -1,53 +0,0 @@ -import "Domain.bond" - -namespace AI - -[Description("An instance of Remote Dependency represents an interaction of the monitored component with a remote component/service like SQL or an HTTP endpoint.")] -struct RemoteDependencyData - : Domain -{ - [Description("Schema version")] - 10: required int32 ver = 2; - - [MaxStringLength("1024")] - [Description("Name of the command initiated with this dependency call. Low cardinality value. Examples are stored procedure name and URL path template.")] - 20: required string name; - - [MaxStringLength("128")] - [Description("Identifier of a dependency call instance. Used for correlation with the request telemetry item corresponding to this dependency call.")] - 30: string id; - - [MaxStringLength("1024")] - [Description("Result code of a dependency call. Examples are SQL error code and HTTP status code.")] - 40: string resultCode; - - [CSType("TimeSpan")] - [Description("Request duration in format: DD.HH:MM:SS.MMMMMM. Must be less than 1000 days.")] - [ActAsRequired("Renaming value to duration.")] - 61: required string duration; - - [Description("Indication of successfull or unsuccessfull call.")] - 120: nullable success = true; - - [MaxStringLength("8192")] - [Description("Command initiated by this dependency call. Examples are SQL statement and HTTP URL's with all query parameters.")] - 151: string data; - - [MaxStringLength("1024")] - [Description("Dependency type name. Very low cardinality value for logical grouping of dependencies and interpretation of other fields like commandName and resultCode. Examples are SQL, Azure table, and HTTP.")] - 162: string type; - - [MaxStringLength("1024")] - [Description("Target site of a dependency call. Examples are server name, host address.")] - 161: string target; - - [Description("Collection of custom properties.")] - [MaxKeyLength("150")] - [MaxValueLength("8192")] - 200: map properties; - - [Description("Collection of custom measurements.")] - [MaxKeyLength("150")] - 300: map measurements; - -} diff --git a/Schema/PublicSchema/RequestData.bond b/Schema/PublicSchema/RequestData.bond deleted file mode 100644 index f26f9268..00000000 --- a/Schema/PublicSchema/RequestData.bond +++ /dev/null @@ -1,48 +0,0 @@ -import "Domain.bond" - -namespace AI - -[Description("An instance of Request represents completion of an external request to the application to do work and contains a summary of that request execution and the results.")] -struct RequestData - : Domain -{ - [Description("Schema version")] - 10: required int32 ver = 2; - - [MaxStringLength("128")] - [Description("Identifier of a request call instance. Used for correlation between request and other telemetry items.")] - 20: required string id; - - [CSType("TimeSpan")] - [Description("Request duration in format: DD.HH:MM:SS.MMMMMM. Must be less than 1000 days.")] - 50: required string duration; - - [MaxStringLength("1024")] - [Description("Result of a request execution. HTTP status code for HTTP requests.")] - 60: required string responseCode; - - [Description("Indication of successfull or unsuccessfull call.")] - 70: required bool success; - - [MaxStringLength("1024")] - [Description("Source of the request. Examples are the instrumentation key of the caller or the ip address of the caller.")] - 29: string source; - - [MaxStringLength("1024")] - [Description("Name of the request. Represents code path taken to process request. Low cardinality value to allow better grouping of requests. For HTTP requests it represents the HTTP method and URL path template like 'GET /values/{id}'.")] - 30: string name; - - [MaxStringLength("2048")] - [Description("Request URL with all query string parameters.")] - 90: string url; - - [Description("Collection of custom properties.")] - [MaxKeyLength("150")] - [MaxValueLength("8192")] - 100: map properties; - - [Description("Collection of custom measurements.")] - [MaxKeyLength("150")] - 200: map measurements; - -} diff --git a/Schema/PublicSchema/SeverityLevel.bond b/Schema/PublicSchema/SeverityLevel.bond deleted file mode 100644 index f336b122..00000000 --- a/Schema/PublicSchema/SeverityLevel.bond +++ /dev/null @@ -1,11 +0,0 @@ -namespace AI - -[Description("Defines the level of severity for the event.")] -enum SeverityLevel -{ - Verbose, - Information, - Warning, - Error, - Critical, -} diff --git a/Schema/PublicSchema/StackFrame.bond b/Schema/PublicSchema/StackFrame.bond deleted file mode 100644 index fc8be5c7..00000000 --- a/Schema/PublicSchema/StackFrame.bond +++ /dev/null @@ -1,25 +0,0 @@ - -namespace AI - -[Description("Stack frame information.")] -struct StackFrame -{ - [Description("Level in the call stack. For the long stacks SDK may not report every function in a call stack.")] - 10: required int32 level; - - [Description("Method name.")] - [MaxStringLength("1024")] - 20: required string method; - - [Description("Name of the assembly (dll, jar, etc.) containing this function.")] - [MaxStringLength("1024")] - 30: string assembly; - - [Description("File name or URL of the method implementation.")] - [MaxStringLength("1024")] - 50: string fileName; - - [Description("Line number of the code implementation.")] - 60: int32 line; - -} diff --git a/Schema/generateSchema.ps1 b/Schema/generateSchema.ps1 deleted file mode 100644 index 32bbf1f3..00000000 --- a/Schema/generateSchema.ps1 +++ /dev/null @@ -1,51 +0,0 @@ -$generatorPath = "C:\src\mseng\AppInsights-Common" -$publicSchemaLocation = "https://raw.githubusercontent.com/Microsoft/ApplicationInsights-Home/master/EndpointSpecs/Schemas/Bond" -$currentDir = $scriptPath = split-path -parent $MyInvocation.MyCommand.Definition -$schemasPath = "$currentDir\PublicSchema" - -#fix path -$generatorPath = "$generatorPath\..\bin\Debug\BondSchemaGenerator\BondSchemaGenerator" - - -##################################################################### -## PUBLIC SCHEMA -##################################################################### -mkdir -Force $schemasPath - -function RegExReplace([string]$fileName, [string]$regex, [string]$replacement="") -{ - $content = Get-Content $fileName - $content = $content -creplace $regex,$replacement - $content | Set-Content $fileName -} - -# Download public schema from the github -@( -"AvailabilityData.bond", -"Base.bond", -"ContextTagKeys.bond", -"Data.bond", -"DataPoint.bond", -"DataPointType.bond", -"Domain.bond", -"Envelope.bond", -"EventData.bond", -"ExceptionData.bond", -"ExceptionDetails.bond", -"MessageData.bond", -"MetricData.bond", -"PageViewData.bond", -"PageViewPerfData.bond", -"RemoteDependencyData.bond", -"RequestData.bond", -"SeverityLevel.bond", -"StackFrame.bond" -) | ForEach-Object { - $fileName = $_ - & Invoke-WebRequest -o "$currentDir\PublicSchema\$fileName" "$publicSchemaLocation/$fileName" - RegExReplace "$currentDir\PublicSchema\$fileName" "`n" "`r`n" -} - -# Generate public schema using bond generator -& "$generatorPath\BondSchemaGenerator.exe" -v -i "$schemasPath\AvailabilityData.bond" -i "$schemasPath\Base.bond" -i "$schemasPath\ContextTagKeys.bond" -i "$schemasPath\Data.bond" -i "$schemasPath\DataPoint.bond" -i "$schemasPath\DataPointType.bond" -i "$schemasPath\Domain.bond" -i "$schemasPath\Envelope.bond" -i "$schemasPath\EventData.bond" -i "$schemasPath\ExceptionData.bond" -i "$schemasPath\ExceptionDetails.bond" -i "$schemasPath\MessageData.bond" -i "$schemasPath\MetricData.bond" -i "$schemasPath\PageViewData.bond" -i "$schemasPath\PageViewPerfData.bond" -i "$schemasPath\RemoteDependencyData.bond" -i "$schemasPath\RequestData.bond" -i "$schemasPath\SeverityLevel.bond" -i "$schemasPath\StackFrame.bond" -o "$currentDir\..\" -e PythonProductLanguage -t PythonProductLayout - diff --git a/applicationinsights/TelemetryClient.py b/applicationinsights/TelemetryClient.py deleted file mode 100644 index a692d7d2..00000000 --- a/applicationinsights/TelemetryClient.py +++ /dev/null @@ -1,297 +0,0 @@ -import datetime -import traceback -import sys -import uuid - - -from applicationinsights import channel - -NULL_CONSTANT_STRING = 'Null' - - -class TelemetryClient(object): - """The telemetry client used for sending all types of telemetry. It serves as the main entry point for - interacting with the Application Insights service. - """ - def __init__(self, instrumentation_key, telemetry_channel=None): - """Initializes a new instance of the class. - - Args: - instrumentation_key (str). the instrumentation key to use for this telemetry client.\n - telemetry_channel (:class:`channel.TelemetryChannel`). the optional telemetry channel to be used instead of - constructing a default one. - """ - if instrumentation_key: - if isinstance(instrumentation_key, channel.TelemetryChannel): - telemetry_channel = instrumentation_key - instrumentation_key = None - else: - raise Exception('Instrumentation key was required but not provided') - self._context = channel.TelemetryContext() - self._context.instrumentation_key = instrumentation_key - self._channel = telemetry_channel or channel.TelemetryChannel() - self._telemetry_processors = [] - - @property - def context(self): - """The context associated with this client. All data objects created by this client will be accompanied by - this value. - - Returns: - :class:`channel.TelemetryContext`. the context instance. - """ - return self._context - - @property - def channel(self): - """The channel associated with this telemetry client. All data created by this client will be passed along with - the :func:`context` object to :class:`channel.TelemetryChannel`'s :func:`write`. - - Returns: - :class:`channel.TelemetryChannel`. the channel instance. - """ - return self._channel - - def flush(self): - """Flushes data in the queue. Data in the queue will be sent either immediately irrespective of what sender is - being used. - """ - self._channel.flush() - - def track_pageview(self, name, url, duration=0, properties=None, measurements=None): - """Send information about the page viewed in the application (a web page for instance). - - Args: - name (str). the name of the page that was viewed.\n - url (str). the URL of the page that was viewed.\n - duration (int). the duration of the page view in milliseconds. (defaults to: 0)\n - properties (dict). the set of custom properties the client wants attached to this data item. (defaults to: None)\n - measurements (dict). the set of custom measurements the client wants to attach to this data item. (defaults to: None) - """ - data = channel.contracts.PageViewData() - data.name = name or NULL_CONSTANT_STRING - data.url = url - data.duration = duration - if properties: - data.properties = properties - if measurements: - data.measurements = measurements - - self.track(data, self._context) - - def track_exception(self, type=None, value=None, tb=None, properties=None, measurements=None): - """ Send information about a single exception that occurred in the application. - - Args: - type (Type). the type of the exception that was thrown.\n - value (:class:`Exception`). the exception that the client wants to send.\n - tb (:class:`Traceback`). the traceback information as returned by :func:`sys.exc_info`.\n - properties (dict). the set of custom properties the client wants attached to this data item. (defaults to: None)\n - measurements (dict). the set of custom measurements the client wants to attach to this data item. (defaults to: None) - """ - if not type or not value or not tb: - type, value, tb = sys.exc_info() - - if not type or not value or not tb: - try: - raise Exception(NULL_CONSTANT_STRING) - except: - type, value, tb = sys.exc_info() - - details = channel.contracts.ExceptionDetails() - details.id = 1 - details.outer_id = 0 - details.type_name = type.__name__ - details.message = str(value) - details.has_full_stack = True - counter = 0 - for tb_frame_file, tb_frame_line, tb_frame_function, tb_frame_text in traceback.extract_tb(tb): - frame = channel.contracts.StackFrame() - frame.assembly = 'Unknown' - frame.file_name = tb_frame_file - frame.level = counter - frame.line = tb_frame_line - frame.method = tb_frame_function - details.parsed_stack.append(frame) - counter += 1 - details.parsed_stack.reverse() - - data = channel.contracts.ExceptionData() - data.handled_at = 'UserCode' - data.exceptions.append(details) - if properties: - data.properties = properties - if measurements: - data.measurements = measurements - self.track(data, self._context) - - def track_event(self, name, properties=None, measurements=None): - """ Send information about a single event that has occurred in the context of the application. - - Args: - name (str). the data to associate to this event.\n - properties (dict). the set of custom properties the client wants attached to this data item. (defaults to: None)\n - measurements (dict). the set of custom measurements the client wants to attach to this data item. (defaults to: None) - """ - data = channel.contracts.EventData() - data.name = name or NULL_CONSTANT_STRING - if properties: - data.properties = properties - if measurements: - data.measurements = measurements - - self.track(data, self._context) - - def track_metric(self, name, value, type=None, count=None, min=None, max=None, std_dev=None, properties=None): - """Send information about a single metric data point that was captured for the application. - - Args: - name (str). the name of the metric that was captured.\n - value (float). the value of the metric that was captured.\n - type (:class:`channel.contracts.DataPointType`). the type of the metric. (defaults to: :func:`channel.contracts.DataPointType.aggregation`)\n - count (int). the number of metrics that were aggregated into this data point. (defaults to: None)\n - min (float). the minimum of all metrics collected that were aggregated into this data point. (defaults to: None)\n - max (float). the maximum of all metrics collected that were aggregated into this data point. (defaults to: None)\n - std_dev (float). the standard deviation of all metrics collected that were aggregated into this data point. (defaults to: None)\n - properties (dict). the set of custom properties the client wants attached to this data item. (defaults to: None) - """ - dataPoint = channel.contracts.DataPoint() - dataPoint.name = name or NULL_CONSTANT_STRING - dataPoint.value = value or 0 - dataPoint.kind = type or channel.contracts.DataPointType.aggregation - dataPoint.count = count - dataPoint.min = min - dataPoint.max = max - dataPoint.std_dev = std_dev - - data = channel.contracts.MetricData() - data.metrics.append(dataPoint) - if properties: - data.properties = properties - - self.track(data, self._context) - - - def track_trace(self, name, properties=None, severity=None): - """Sends a single trace statement. - - Args: - name (str). the trace statement.\n - properties (dict). the set of custom properties the client wants attached to this data item. (defaults to: None)\n - severity (str). the severity level of this trace, one of DEBUG, INFO, WARNING, ERROR, CRITICAL - """ - data = channel.contracts.MessageData() - data.message = name or NULL_CONSTANT_STRING - if properties: - data.properties = properties - if severity is not None: - data.severity_level = channel.contracts.MessageData.PYTHON_LOGGING_LEVELS.get(severity) - - self.track(data, self._context) - - - def track_request(self, name, url, success, start_time=None, duration=None, response_code=None, http_method=None, properties=None, measurements=None, request_id=None): - """Sends a single request that was captured for the application. - - Args: - name (str). the name for this request. All requests with the same name will be grouped together.\n - url (str). the actual URL for this request (to show in individual request instances).\n - success (bool). true if the request ended in success, false otherwise.\n - start_time (str). the start time of the request. The value should look the same as the one returned by :func:`datetime.isoformat()` (defaults to: None)\n - duration (int). the number of milliseconds that this request lasted. (defaults to: None)\n - response_code (str). the response code that this request returned. (defaults to: None)\n - http_method (str). the HTTP method that triggered this request. (defaults to: None)\n - properties (dict). the set of custom properties the client wants attached to this data item. (defaults to: None)\n - measurements (dict). the set of custom measurements the client wants to attach to this data item. (defaults to: None)\n - request_id (str). the id for this request. If None, a new uuid will be generated. (defaults to: None) - """ - data = channel.contracts.RequestData() - data.id = request_id or str(uuid.uuid4()) - data.name = name - data.url = url - data.success = success - data.start_time = start_time or datetime.datetime.utcnow().isoformat() + 'Z' - data.duration = self.__ms_to_duration(duration) - data.response_code = str(response_code) or '200' - data.http_method = http_method or 'GET' - if properties: - data.properties = properties - if measurements: - data.measurements = measurements - - self.track(data, self._context) - - def track_dependency(self, name, data, type=None, target=None, duration=None, success=None, result_code=None, properties=None, measurements=None, dependency_id=None): - """Sends a single dependency telemetry that was captured for the application. - - Args: - name (str). the name of the command initiated with this dependency call. Low cardinality value. Examples are stored procedure name and URL path template.\n - data (str). the command initiated by this dependency call. Examples are SQL statement and HTTP URL with all query parameters.\n - type (str). the dependency type name. Low cardinality value for logical grouping of dependencies and interpretation of other fields like commandName and resultCode. Examples are SQL, Azure table, and HTTP. (default to: None)\n - target (str). the target site of a dependency call. Examples are server name, host address. (default to: None)\n - duration (int). the number of milliseconds that this dependency call lasted. (defaults to: None)\n - success (bool). true if the dependency call ended in success, false otherwise. (defaults to: None)\n - result_code (str). the result code of a dependency call. Examples are SQL error code and HTTP status code. (defaults to: None)\n - properties (dict). the set of custom properties the client wants attached to this data item. (defaults to: None)\n - measurements (dict). the set of custom measurements the client wants to attach to this data item. (defaults to: None)\n - id (str). the id for this dependency call. If None, a new uuid will be generated. (defaults to: None) - """ - dependency_data = channel.contracts.RemoteDependencyData() - dependency_data.id = dependency_id or str(uuid.uuid4()) - dependency_data.name = name - dependency_data.data = data - dependency_data.type = type - dependency_data.target = target - dependency_data.duration = self.__ms_to_duration(duration) - dependency_data.success = success - dependency_data.result_code = str(result_code) or '200' - if properties: - dependency_data.properties = properties - if measurements: - dependency_data.measurements = measurements - - self.track(dependency_data, self._context) - - def track(self, data, context): - if self.run_telemetry_processors(data, context): - self.channel.write(data, context) - - def add_telemetry_processor(self, telemetry_processor): - """Adds telemetry processor to the collection. Telemetry processors will be called one by one - before telemetry item is pushed for sending and in the order they were added. - - Args: - telemetry_processor (function). Takes a telemetry item, and context object and returns boolean - that determines if the event is passed to the server (False = Filtered) - """ - if telemetry_processor is None: - raise TypeError('telemetry_processor cannot be None.') - - self._telemetry_processors.insert(0, telemetry_processor) - - def run_telemetry_processors(self, data, context): - allow_data_through = True - - try: - for processor in self._telemetry_processors: - if processor(data, context) == False: - allow_data_through = False - break - except: - allow_data_through = True - return allow_data_through - - @staticmethod - def __ms_to_duration(duration_ms): - local_duration = duration_ms or 0 - duration_parts = [] - for multiplier in [1000, 60, 60, 24]: - duration_parts.append(local_duration % multiplier) - local_duration //= multiplier - - duration_parts.reverse() - duration = '%02d:%02d:%02d.%03d' % (duration_parts[0], duration_parts[1], duration_parts[2], duration_parts[3]) - if local_duration: - duration = '%d.%s' % (local_duration, duration) - - return duration diff --git a/applicationinsights/__init__.py b/applicationinsights/__init__.py deleted file mode 100644 index f7fb5980..00000000 --- a/applicationinsights/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -from .TelemetryClient import TelemetryClient -from . import channel -from . import logging -from . import requests \ No newline at end of file diff --git a/applicationinsights/channel/AsynchronousQueue.py b/applicationinsights/channel/AsynchronousQueue.py deleted file mode 100644 index 0e4bff2c..00000000 --- a/applicationinsights/channel/AsynchronousQueue.py +++ /dev/null @@ -1,41 +0,0 @@ -from .QueueBase import QueueBase -from threading import Event - -class AsynchronousQueue(QueueBase): - """An asynchronous queue for use in conjunction with the :class:`AsynchronousSender`. The queue - will notify the sender that it needs to pick up items when it reaches :func:`max_queue_length`, or - when the consumer calls :func:`flush` via the :func:`flush_notification` event. - """ - def __init__(self, *args, **kwargs): - """Initializes a new instance of the class. - """ - self._flush_notification = Event() - QueueBase.__init__(self, *args, **kwargs) - - @property - def flush_notification(self): - """The flush notification :class:`Event` that the :func:`sender` will use to get notified - that a flush is needed. - - Returns: - :class:`Event`. object that the :func:`sender` can wait on. - """ - return self._flush_notification - - def put(self, item): - """Adds the passed in item object to the queue and notifies the :func:`sender` to start an asynchronous - send operation by calling :func:`start`. - - Args: - item (:class:`contracts.Envelope`) the telemetry envelope object to send to the service. - """ - QueueBase.put(self, item) - if self.sender: - self.sender.start() - - def flush(self): - """Flushes the current queue by notifying the :func:`sender` via the :func:`flush_notification` event. - """ - self._flush_notification.set() - if self.sender: - self.sender.start() diff --git a/applicationinsights/channel/AsynchronousSender.py b/applicationinsights/channel/AsynchronousSender.py deleted file mode 100644 index 19389a59..00000000 --- a/applicationinsights/channel/AsynchronousSender.py +++ /dev/null @@ -1,147 +0,0 @@ -from .SenderBase import SenderBase, DEFAULT_ENDPOINT_URL -from threading import Lock, Thread - -class AsynchronousSender(SenderBase): - """An asynchronous sender that works in conjunction with the :class:`AsynchronousQueue`. The sender object will - start a worker thread that will pull items from the :func:`queue`. The thread will be created when the client - calls :func:`start` and will check for queue items every :func:`send_interval` seconds. The worker thread can - also be forced to check the queue by setting the :func:`flush_notification` event. - - - If no items are found, the thread will go back to sleep. - - If items are found, the worker thread will send items to the specified service in batches of :func:`send_buffer_size`. - - If no queue items are found for :func:`send_time` seconds, the worker thread will shut down (and :func:`start` will - need to be called again). - """ - def __init__(self, service_endpoint_uri=None): - """Initializes a new instance of the class. - - Args: - sender (String) service_endpoint_uri the address of the service to send telemetry data to. - """ - self._send_interval = 1.0 - self._send_remaining_time = 0 - self._send_time = 3.0 - self._lock_send_remaining_time = Lock() - SenderBase.__init__(self, service_endpoint_uri or DEFAULT_ENDPOINT_URL) - - @property - def send_interval(self): - """The time span in seconds at which the the worker thread will check the :func:`queue` for items (defaults to: 1.0). - - Args: - value (int) the interval in seconds. - - Returns: - int. the interval in seconds. - """ - return self._send_interval - - @send_interval.setter - def send_interval(self, value): - """The time span in seconds at which the the worker thread will check the :func:`queue` for items (defaults to: 1.0). - - Args: - value (int) the interval in seconds. - - Returns: - int. the interval in seconds. - """ - self._send_interval = value - - @property - def send_time(self): - """The time span in seconds at which the the worker thread will check the :func:`queue` for items (defaults to: 1.0). - - Args: - value (int) the interval in seconds. - - Returns: - int. the interval in seconds. - """ - return self._send_time - - @send_time.setter - def send_time(self, value): - """The time span in seconds at which the the worker thread will check the :func:`queue` for items (defaults to: 1.0). - - Args: - value (int) the interval in seconds. - - Returns: - int. the interval in seconds. - """ - self._send_time = value - - def start(self): - """Starts a new sender thread if none is not already there - """ - with self._lock_send_remaining_time: - if self._send_remaining_time <= 0.0: - local_send_interval = self._send_interval - if self._send_interval < 0.1: - local_send_interval = 0.1 - self._send_remaining_time = self._send_time - if self._send_remaining_time < local_send_interval: - self._send_remaining_time = local_send_interval - thread = Thread(target=self._run) - thread.daemon = True - thread.start() - - def stop(self): - """Gracefully stops the sender thread if one is there. - """ - with self._lock_send_remaining_time: - self._send_remaining_time = 0.0 - - def _run(self): - # save the queue locally - local_queue = self._queue - if not local_queue: - self.stop() - return - - # fix up the send interval (can't be lower than 100ms) - local_send_interval = self._send_interval - if self._send_interval < 0.1: - local_send_interval = 0.1 - local_send_time = self._send_time - if local_send_time < local_send_interval: - local_send_time = local_send_interval - while True: - while True: - # get at most send_buffer_size items from the queue - counter = self._send_buffer_size - data = [] - while counter > 0: - item = local_queue.get() - if not item: - break - data.append(item) - counter -= 1 - - # if we didn't get any items from the queue, we're done here - if len(data) == 0: - break - - # reset the send time - with self._lock_send_remaining_time: - self._send_remaining_time = local_send_time - - # finally send the data - self.send(data) - - # wait at most send_interval (or until we get signalled) - result = local_queue.flush_notification.wait(local_send_interval) - if result: - local_queue.flush_notification.clear() - continue - - # decrement the remaining time - local_remaining_time = 0 - with self._lock_send_remaining_time: - self._send_remaining_time -= local_send_interval - local_remaining_time = self._send_remaining_time - - if local_remaining_time <= 0: - break diff --git a/applicationinsights/channel/NullSender.py b/applicationinsights/channel/NullSender.py deleted file mode 100644 index 68cb06d7..00000000 --- a/applicationinsights/channel/NullSender.py +++ /dev/null @@ -1,17 +0,0 @@ -from .SenderBase import SenderBase - -class NullSender(SenderBase): - """A sender class that does not send data. Useful for debug mode, when - telemetry may not be desired, with no changes to the object model. - """ - def __init__(self, *args, **kwargs): - super(NullSender, self).__init__("nil-endpoint", *args, **kwargs) - - def send(self, data): - pass - - def start(self): - pass - - def stop(self): - pass diff --git a/applicationinsights/channel/QueueBase.py b/applicationinsights/channel/QueueBase.py deleted file mode 100644 index b42cf1b2..00000000 --- a/applicationinsights/channel/QueueBase.py +++ /dev/null @@ -1,112 +0,0 @@ -try: - # Python 2.x - from Queue import Queue, Empty -except ImportError: - # Python 3.x - from queue import Queue, Empty - -try: - from persistqueue import Empty as PersistEmpty - from persistqueue import Queue as PersistQueue -except ImportError: - PersistEmpty = Empty - PersistQueue = None - - -class QueueBase(object): - """The base class for all types of queues for use in conjunction with an implementation of :class:`SenderBase`. - - The queue will notify the sender that it needs to pick up items when it reaches :func:`max_queue_length`, - or when the consumer calls :func:`flush`. - """ - def __init__(self, sender, persistence_path=''): - """Initializes a new instance of the class. - - Args: - sender (:class:`SenderBase`) the sender object that will be used in conjunction with this queue. - persistence_path (str) if set, persist the queue on disk into the provided directory. - """ - if persistence_path and PersistQueue is None: - raise ValueError('persistence_path argument requires persist-queue dependency to be installed') - elif persistence_path: - self._queue = PersistQueue(persistence_path) - else: - self._queue = Queue() - - self._persistence_path = persistence_path - self._max_queue_length = 500 - self._sender = sender - if sender: - self._sender.queue = self - - @property - def max_queue_length(self): - """The maximum number of items that will be held by the queue before the queue will call the :func:`flush` - method. - - Args: - value (int). the maximum queue length. The minimum allowed value is 1. - - Returns: - int. the maximum queue size. (defaults to: 500) - """ - return self._max_queue_length - - @max_queue_length.setter - def max_queue_length(self, value): - """The maximum number of items that will be held by the queue before the queue will call the :func:`flush` - method. - - Args: - value (int): the maximum queue length. The minimum allowed value is 1. - - Returns: - int. the maximum queue size. (defaults to: 500) - """ - if value < 1: - value = 1 - self._max_queue_length = value - - @property - def sender(self): - """The sender that is associated with this queue that this queue will use to send data to the service. - - Returns: - :class:`SenderBase`. the sender object. - """ - return self._sender - - def put(self, item): - """Adds the passed in item object to the queue and calls :func:`flush` if the size of the queue is larger - than :func:`max_queue_length`. This method does nothing if the passed in item is None. - - Args: - item (:class:`contracts.Envelope`) item the telemetry envelope object to send to the service. - """ - if not item: - return - self._queue.put(item) - if self._queue.qsize() >= self._max_queue_length: - self.flush() - - def get(self): - """Gets a single item from the queue and returns it. If the queue is empty, this method will return None. - - Returns: - :class:`contracts.Envelope`. a telemetry envelope object or None if the queue is empty. - """ - try: - item = self._queue.get_nowait() - except (Empty, PersistEmpty): - return None - - if self._persistence_path: - self._queue.task_done() - - return item - - def flush(self): - """Flushes the current queue by notifying the {#sender}. This method needs to be overridden by a concrete - implementations of the queue class. - """ - pass \ No newline at end of file diff --git a/applicationinsights/channel/SenderBase.py b/applicationinsights/channel/SenderBase.py deleted file mode 100644 index 44bc1f13..00000000 --- a/applicationinsights/channel/SenderBase.py +++ /dev/null @@ -1,148 +0,0 @@ -import json - -try: - # Python 2.x - import urllib2 as HTTPClient - from urllib2 import HTTPError -except ImportError: - # Python 3.x - import urllib.request as HTTPClient - from urllib.error import HTTPError - -DEFAULT_ENDPOINT_URL = 'https://dc.services.visualstudio.com/v2/track' - -class SenderBase(object): - """The base class for all types of senders for use in conjunction with an implementation of :class:`QueueBase`. - - The queue will notify the sender that it needs to pick up items. The concrete sender implementation will - listen to these notifications and will pull items from the queue getting at most :func:`send_buffer_size` items. - It will then call :func:`send` using the list of items pulled from the queue. - """ - def __init__(self, service_endpoint_uri): - """Initializes a new instance of the class. - - Args: - service_endpoint_uri (str) the address of the service to send telemetry data to. - """ - self._service_endpoint_uri = service_endpoint_uri - self._queue = None - self._send_buffer_size = 100 - self._timeout = 10 - - @property - def service_endpoint_uri(self): - """The HTTP or HTTPS endpoint that this sender will send data to. - - Args: - value (str). the service endpoint URI. - - Returns: - str. the service endpoint URI. - """ - return self._service_endpoint_uri - - @service_endpoint_uri.setter - def service_endpoint_uri(self, value): - """The service endpoint URI where this sender will send data to. - - Args: - value (str). the service endpoint URI. - - Returns: - str. the service endpoint URI. - """ - self._service_endpoint_uri = value - - @property - def queue(self): - """The queue that this sender is draining. While :class:`SenderBase` doesn't implement any means of doing - so, derivations of this class do. - - Args: - value (:class:`QueueBase`). the queue instance that this sender is draining. - - Returns: - :class:`QueueBase`. the queue instance that this sender is draining. - """ - return self._queue - - @property - def send_timeout(self): - """Time in seconds that the sender should wait before giving up.""" - return self._timeout - - @send_timeout.setter - def send_timeout(self, seconds): - """Configures the timeout in seconds the sender waits for a response for the server. - - Args: - seconds(float). Timeout in seconds. - """ - - self._timeout = seconds - - @queue.setter - def queue(self, value): - """The queue that this sender is draining. While :class:`SenderBase` doesn't implement any means of doing - so, derivations of this class do. - - Args: - value (:class:`QueueBase`). the queue instance that this sender is draining. - - Returns: - :class:`QueueBase`. the queue instance that this sender is draining. - """ - self._queue = value - - @property - def send_buffer_size(self): - """The buffer size for a single batch of telemetry. This is the maximum number of items in a single service - request that this sender is going to send. - - Args: - value (int). the maximum number of items in a telemetry batch. - - Returns: - int. the maximum number of items in a telemetry batch. - """ - return self._send_buffer_size - - @send_buffer_size.setter - def send_buffer_size(self, value): - """The buffer size for a single batch of telemetry. This is the maximum number of items in a single service - request that this sender is going to send. - - Args: - value (int). the maximum number of items in a telemetry batch. - - Returns: - int. the maximum number of items in a telemetry batch. - """ - if value < 1: - value = 1 - self._send_buffer_size = value - - def send(self, data_to_send): - """ Immediately sends the data passed in to :func:`service_endpoint_uri`. If the service request fails, the - passed in items are pushed back to the :func:`queue`. - - Args: - data_to_send (Array): an array of :class:`contracts.Envelope` objects to send to the service. - """ - request_payload = json.dumps([ a.write() for a in data_to_send ]) - - request = HTTPClient.Request(self._service_endpoint_uri, bytearray(request_payload, 'utf-8'), { 'Accept': 'application/json', 'Content-Type' : 'application/json; charset=utf-8' }) - try: - response = HTTPClient.urlopen(request, timeout=self._timeout) - status_code = response.getcode() - if 200 <= status_code < 300: - return - except HTTPError as e: - if e.getcode() == 400: - return - except Exception as e: - pass - - # Add our unsent data back on to the queue - for data in data_to_send: - self._queue.put(data) diff --git a/applicationinsights/channel/SynchronousQueue.py b/applicationinsights/channel/SynchronousQueue.py deleted file mode 100644 index e4c803ca..00000000 --- a/applicationinsights/channel/SynchronousQueue.py +++ /dev/null @@ -1,31 +0,0 @@ -from .QueueBase import QueueBase - -class SynchronousQueue(QueueBase): - """A synchronous queue for use in conjunction with the :class:`SynchronousSender`. The queue will call - :func:`send` on :func:`sender` when it reaches :func:`max_queue_length`, or when the consumer calls - :func:`flush`. - - .. code:: python - - from application_insights.channel import SynchronousQueue - queue = SynchronousQueue(None) - queue.max_queue_length = 1 - queue.put(1) - """ - def flush(self): - """Flushes the current queue by by calling :func:`sender`'s :func:`send` method. - """ - local_sender = self.sender - if not local_sender: - return - while True: - # get at most send_buffer_size items and send them - data = [] - while len(data) < local_sender.send_buffer_size: - item = self.get() - if not item: - break - data.append(item) - if len(data) == 0: - break - local_sender.send(data) diff --git a/applicationinsights/channel/SynchronousSender.py b/applicationinsights/channel/SynchronousSender.py deleted file mode 100644 index 7daf986c..00000000 --- a/applicationinsights/channel/SynchronousSender.py +++ /dev/null @@ -1,13 +0,0 @@ -from .SenderBase import SenderBase, DEFAULT_ENDPOINT_URL - -class SynchronousSender(SenderBase): - """A synchronous sender that works in conjunction with the :class:`SynchronousQueue`. The queue will call - :func:`send` on the current instance with the data to send. - """ - def __init__(self, service_endpoint_uri=None): - """Initializes a new instance of the class. - - Args: - sender (String) service_endpoint_uri the address of the service to send telemetry data to. - """ - SenderBase.__init__(self, service_endpoint_uri or DEFAULT_ENDPOINT_URL) \ No newline at end of file diff --git a/applicationinsights/channel/TelemetryChannel.py b/applicationinsights/channel/TelemetryChannel.py deleted file mode 100644 index a9f7934b..00000000 --- a/applicationinsights/channel/TelemetryChannel.py +++ /dev/null @@ -1,123 +0,0 @@ -import datetime -import sys - -from .SynchronousQueue import SynchronousQueue -from .SynchronousSender import SynchronousSender -from .TelemetryContext import TelemetryContext -from applicationinsights.channel import contracts - -platform_moniker = 'py2' -if sys.version_info >= (3, 0): - platform_moniker = 'py3' - -# set up internal context -internal_context = contracts.Internal() -internal_context.sdk_version = platform_moniker + ':0.11.10' - - -class TelemetryChannel(object): - """The telemetry channel is responsible for constructing a :class:`contracts.Envelope` object from the passed in - data and specified telemetry context. - - .. code:: python - - from application_insights.channel import TelemetryChannel, contracts - channel = TelemetryChannel() - event = contracts.EventData() - event.name = 'My event' - channel.write(event) - """ - - def __init__(self, context=None, queue=None): - """Initializes a new instance of the class. - - Args: - context (:class:`TelemetryContext') the telemetry context to use when sending telemetry data.\n - queue (:class:`QueueBase`) the queue to enqueue the resulting :class:`contracts.Envelope` to. - """ - self._context = context or TelemetryContext() - self._queue = queue or SynchronousQueue(SynchronousSender()) - - @property - def context(self): - """The context associated with this channel. All :class:`contracts.Envelope` objects created by this channel - will use this value if it's present or if none is specified as part of the :func:`write` call. - - Returns: - (:class:`TelemetryContext`). the context instance (defaults to: TelemetryContext()) - """ - return self._context - - @property - def queue(self): - """The queue associated with this channel. All :class:`contracts.Envelope` objects created by this channel - will be pushed to this queue. - - Returns: - (:class:`QueueBase`). the queue instance (defaults to: SynchronousQueue()) - """ - return self._queue - - @property - def sender(self): - """The sender associated with this channel. This instance will be used to transmit telemetry to the service. - - Returns: - (:class:`SenderBase`). the sender instance (defaults to: SynchronousSender()) - """ - return self._queue.sender - - def flush(self): - """Flushes the enqueued data by calling :func:`flush` on :func:`queue`. - """ - self._queue.flush() - - def write(self, data, context=None): - """Enqueues the passed in data to the :func:`queue`. If the caller specifies a context as well, it will - take precedence over the instance in :func:`context`. - - Args: - data (object). data the telemetry data to send. This will be wrapped in an :class:`contracts.Envelope` - before being enqueued to the :func:`queue`. - context (:class:`TelemetryContext`). context the override context to use when constructing the - :class:`contracts.Envelope`. - """ - local_context = context or self._context - if not local_context: - raise Exception('Context was required but not provided') - - if not data: - raise Exception('Data was required but not provided') - - envelope = contracts.Envelope() - envelope.name = data.ENVELOPE_TYPE_NAME - envelope.time = datetime.datetime.utcnow().isoformat() + 'Z' - envelope.ikey = local_context.instrumentation_key - tags = envelope.tags - for prop_context in [self._context, context]: - if not prop_context: - continue - for key, value in self._write_tags(prop_context): - tags[key] = value - envelope.data = contracts.Data() - envelope.data.base_type = data.DATA_TYPE_NAME - for prop_context in [context, self._context]: - if not prop_context: - continue - if hasattr(data, 'properties') and prop_context.properties: - properties = data.properties - for key in prop_context.properties: - if key not in properties: - properties[key] = prop_context.properties[key] - envelope.data.base_data = data - - self._queue.put(envelope) - - def _write_tags(self, context): - for item in [internal_context, - context.device, context.cloud, context.application, context.user, - context.session, context.location, context.operation]: - if not item: - continue - for pair in item.write().items(): - yield pair diff --git a/applicationinsights/channel/TelemetryContext.py b/applicationinsights/channel/TelemetryContext.py deleted file mode 100644 index 82091a5e..00000000 --- a/applicationinsights/channel/TelemetryContext.py +++ /dev/null @@ -1,54 +0,0 @@ -import platform -import locale - -from applicationinsights.channel import contracts - -# save off whatever is currently there -existing_device_initialize = contracts.Device._initialize -def device_initialize(self): - """ The device initializer used to assign special properties to all device context objects""" - existing_device_initialize(self) - self.type = 'Other' - self.id = platform.node() - self.os_version = platform.version() - self.locale = locale.getdefaultlocale()[0] - -# assign the device context initializer -contracts.Device._initialize = device_initialize - -class TelemetryContext(object): - """Represents the context for sending telemetry to the Application Insights service. - - .. code:: python - - context = TelemetryContext() - context.instrumentation_key = '' - context.application.ver = '1.2.3' - context.device.id = 'My current device' - context.device.oem_name = 'Asus' - context.device.model = 'X31A' - context.device.type = "Other" - context.user.id = 'santa@northpole.net' - track_trace('My trace with context') - """ - def __init__(self): - """Initializes a new instance of the class. - """ - self.instrumentation_key = None - self.device = contracts.Device() - self.cloud = contracts.Cloud() - self.application = contracts.Application() - self.user = contracts.User() - self.session = contracts.Session() - self.operation = contracts.Operation() - self.location = contracts.Location() - self._properties = {} - - @property - def properties(self): - """The property context. This contains free-form properties that you can add to your telemetry. - - Returns: - (dict). the context object. - """ - return self._properties diff --git a/applicationinsights/channel/__init__.py b/applicationinsights/channel/__init__.py deleted file mode 100644 index 889365cb..00000000 --- a/applicationinsights/channel/__init__.py +++ /dev/null @@ -1,10 +0,0 @@ -from .AsynchronousQueue import AsynchronousQueue -from .AsynchronousSender import AsynchronousSender -from .SenderBase import SenderBase -from .QueueBase import QueueBase -from .SynchronousQueue import SynchronousQueue -from .SynchronousSender import SynchronousSender -from .TelemetryChannel import TelemetryChannel -from .TelemetryContext import TelemetryContext -from .NullSender import NullSender -from . import contracts diff --git a/applicationinsights/channel/contracts/Application.py b/applicationinsights/channel/contracts/Application.py deleted file mode 100644 index 7db829d1..00000000 --- a/applicationinsights/channel/contracts/Application.py +++ /dev/null @@ -1,54 +0,0 @@ -import collections -import copy -from .Utils import _write_complex_object - -class Application(object): - """Data contract class for type Application. - """ - _defaults = collections.OrderedDict([ - ('ai.application.ver', None) - ]) - - def __init__(self): - """Initializes a new instance of the class. - """ - self._values = { - } - self._initialize() - - @property - def ver(self): - """The ver property. - - Returns: - (string). the property value. (defaults to: None) - """ - if 'ai.application.ver' in self._values: - return self._values['ai.application.ver'] - return self._defaults['ai.application.ver'] - - @ver.setter - def ver(self, value): - """The ver property. - - Args: - value (string). the property value. - """ - if value == self._defaults['ai.application.ver'] and 'ai.application.ver' in self._values: - del self._values['ai.application.ver'] - else: - self._values['ai.application.ver'] = value - - def _initialize(self): - """Initializes the current instance of the object. - """ - pass - - def write(self): - """Writes the contents of this object and returns the content as a dict object. - - Returns: - (dict). the object that represents the same data as the current instance. - """ - return _write_complex_object(self._defaults, self._values) - diff --git a/applicationinsights/channel/contracts/AvailabilityData.py b/applicationinsights/channel/contracts/AvailabilityData.py deleted file mode 100644 index 4ad072e7..00000000 --- a/applicationinsights/channel/contracts/AvailabilityData.py +++ /dev/null @@ -1,228 +0,0 @@ -import collections -import copy -from .Utils import _write_complex_object - -class AvailabilityData(object): - """Data contract class for type AvailabilityData. - """ - _defaults = collections.OrderedDict([ - ('ver', 2), - ('id', None), - ('name', None), - ('duration', None), - ('success', None), - ('runLocation', None), - ('message', None), - ('properties', {}), - ('measurements', {}) - ]) - - def __init__(self): - """Initializes a new instance of the class. - """ - self._values = { - 'ver': 2, - 'id': None, - 'name': None, - 'duration': None, - 'success': None, - } - self._initialize() - - @property - def ver(self): - """The ver property. - - Returns: - (int). the property value. (defaults to: 2) - """ - return self._values['ver'] - - @ver.setter - def ver(self, value): - """The ver property. - - Args: - value (int). the property value. - """ - self._values['ver'] = value - - @property - def id(self): - """The id property. - - Returns: - (string). the property value. (defaults to: None) - """ - return self._values['id'] - - @id.setter - def id(self, value): - """The id property. - - Args: - value (string). the property value. - """ - self._values['id'] = value - - @property - def name(self): - """The name property. - - Returns: - (string). the property value. (defaults to: None) - """ - return self._values['name'] - - @name.setter - def name(self, value): - """The name property. - - Args: - value (string). the property value. - """ - self._values['name'] = value - - @property - def duration(self): - """The duration property. - - Returns: - (string). the property value. (defaults to: None) - """ - return self._values['duration'] - - @duration.setter - def duration(self, value): - """The duration property. - - Args: - value (string). the property value. - """ - self._values['duration'] = value - - @property - def success(self): - """The success property. - - Returns: - (bool). the property value. (defaults to: None) - """ - return self._values['success'] - - @success.setter - def success(self, value): - """The success property. - - Args: - value (bool). the property value. - """ - self._values['success'] = value - - @property - def run_location(self): - """The run_location property. - - Returns: - (string). the property value. (defaults to: None) - """ - if 'runLocation' in self._values: - return self._values['runLocation'] - return self._defaults['runLocation'] - - @run_location.setter - def run_location(self, value): - """The run_location property. - - Args: - value (string). the property value. - """ - if value == self._defaults['runLocation'] and 'runLocation' in self._values: - del self._values['runLocation'] - else: - self._values['runLocation'] = value - - @property - def message(self): - """The message property. - - Returns: - (string). the property value. (defaults to: None) - """ - if 'message' in self._values: - return self._values['message'] - return self._defaults['message'] - - @message.setter - def message(self, value): - """The message property. - - Args: - value (string). the property value. - """ - if value == self._defaults['message'] and 'message' in self._values: - del self._values['message'] - else: - self._values['message'] = value - - @property - def properties(self): - """The properties property. - - Returns: - (hash). the property value. (defaults to: {}) - """ - if 'properties' in self._values: - return self._values['properties'] - self._values['properties'] = copy.deepcopy(self._defaults['properties']) - return self._values['properties'] - - @properties.setter - def properties(self, value): - """The properties property. - - Args: - value (hash). the property value. - """ - if value == self._defaults['properties'] and 'properties' in self._values: - del self._values['properties'] - else: - self._values['properties'] = value - - @property - def measurements(self): - """The measurements property. - - Returns: - (hash). the property value. (defaults to: {}) - """ - if 'measurements' in self._values: - return self._values['measurements'] - self._values['measurements'] = copy.deepcopy(self._defaults['measurements']) - return self._values['measurements'] - - @measurements.setter - def measurements(self, value): - """The measurements property. - - Args: - value (hash). the property value. - """ - if value == self._defaults['measurements'] and 'measurements' in self._values: - del self._values['measurements'] - else: - self._values['measurements'] = value - - def _initialize(self): - """Initializes the current instance of the object. - """ - pass - - def write(self): - """Writes the contents of this object and returns the content as a dict object. - - Returns: - (dict). the object that represents the same data as the current instance. - """ - return _write_complex_object(self._defaults, self._values) - diff --git a/applicationinsights/channel/contracts/Base.py b/applicationinsights/channel/contracts/Base.py deleted file mode 100644 index 12bb0e5e..00000000 --- a/applicationinsights/channel/contracts/Base.py +++ /dev/null @@ -1,54 +0,0 @@ -import collections -import copy -from .Utils import _write_complex_object - -class Base(object): - """Data contract class for type Base. - """ - _defaults = collections.OrderedDict([ - ('baseType', None) - ]) - - def __init__(self): - """Initializes a new instance of the class. - """ - self._values = { - } - self._initialize() - - @property - def base_type(self): - """The base_type property. - - Returns: - (string). the property value. (defaults to: None) - """ - if 'baseType' in self._values: - return self._values['baseType'] - return self._defaults['baseType'] - - @base_type.setter - def base_type(self, value): - """The base_type property. - - Args: - value (string). the property value. - """ - if value == self._defaults['baseType'] and 'baseType' in self._values: - del self._values['baseType'] - else: - self._values['baseType'] = value - - def _initialize(self): - """Initializes the current instance of the object. - """ - pass - - def write(self): - """Writes the contents of this object and returns the content as a dict object. - - Returns: - (dict). the object that represents the same data as the current instance. - """ - return _write_complex_object(self._defaults, self._values) - diff --git a/applicationinsights/channel/contracts/Cloud.py b/applicationinsights/channel/contracts/Cloud.py deleted file mode 100644 index ec86570c..00000000 --- a/applicationinsights/channel/contracts/Cloud.py +++ /dev/null @@ -1,78 +0,0 @@ -import collections -import copy -from .Utils import _write_complex_object - -class Cloud(object): - """Data contract class for type Cloud. - """ - _defaults = collections.OrderedDict([ - ('ai.cloud.role', None), - ('ai.cloud.roleInstance', None) - ]) - - def __init__(self): - """Initializes a new instance of the class. - """ - self._values = { - } - self._initialize() - - @property - def role(self): - """The role property. - - Returns: - (string). the property value. (defaults to: None) - """ - if 'ai.cloud.role' in self._values: - return self._values['ai.cloud.role'] - return self._defaults['ai.cloud.role'] - - @role.setter - def role(self, value): - """The role property. - - Args: - value (string). the property value. - """ - if value == self._defaults['ai.cloud.role'] and 'ai.cloud.role' in self._values: - del self._values['ai.cloud.role'] - else: - self._values['ai.cloud.role'] = value - - @property - def role_instance(self): - """The role_instance property. - - Returns: - (string). the property value. (defaults to: None) - """ - if 'ai.cloud.roleInstance' in self._values: - return self._values['ai.cloud.roleInstance'] - return self._defaults['ai.cloud.roleInstance'] - - @role_instance.setter - def role_instance(self, value): - """The role_instance property. - - Args: - value (string). the property value. - """ - if value == self._defaults['ai.cloud.roleInstance'] and 'ai.cloud.roleInstance' in self._values: - del self._values['ai.cloud.roleInstance'] - else: - self._values['ai.cloud.roleInstance'] = value - - def _initialize(self): - """Initializes the current instance of the object. - """ - pass - - def write(self): - """Writes the contents of this object and returns the content as a dict object. - - Returns: - (dict). the object that represents the same data as the current instance. - """ - return _write_complex_object(self._defaults, self._values) - diff --git a/applicationinsights/channel/contracts/Data.py b/applicationinsights/channel/contracts/Data.py deleted file mode 100644 index 9ecbaf1f..00000000 --- a/applicationinsights/channel/contracts/Data.py +++ /dev/null @@ -1,74 +0,0 @@ -import collections -import copy -from .Utils import _write_complex_object - -class Data(object): - """Data contract class for type Data. - """ - _defaults = collections.OrderedDict([ - ('baseType', None), - ('baseData', None) - ]) - - def __init__(self): - """Initializes a new instance of the class. - """ - self._values = { - 'baseData': None - } - self._initialize() - - @property - def base_type(self): - """The base_type property. - - Returns: - (string). the property value. (defaults to: None) - """ - if 'baseType' in self._values: - return self._values['baseType'] - return self._defaults['baseType'] - - @base_type.setter - def base_type(self, value): - """The base_type property. - - Args: - value (string). the property value. - """ - if value == self._defaults['baseType'] and 'baseType' in self._values: - del self._values['baseType'] - else: - self._values['baseType'] = value - - @property - def base_data(self): - """The base_data property. - - Returns: - (object). the property value. (defaults to: None) - """ - return self._values['baseData'] - - @base_data.setter - def base_data(self, value): - """The base_data property. - - Args: - value (object). the property value. - """ - self._values['baseData'] = value - - def _initialize(self): - """Initializes the current instance of the object. - """ - pass - - def write(self): - """Writes the contents of this object and returns the content as a dict object. - - Returns: - (dict). the object that represents the same data as the current instance. - """ - return _write_complex_object(self._defaults, self._values) - diff --git a/applicationinsights/channel/contracts/DataPoint.py b/applicationinsights/channel/contracts/DataPoint.py deleted file mode 100644 index 3edd05f8..00000000 --- a/applicationinsights/channel/contracts/DataPoint.py +++ /dev/null @@ -1,216 +0,0 @@ -import collections -import copy -from .Utils import _write_complex_object -from .DataPointType import DataPointType - -class DataPoint(object): - """Data contract class for type DataPoint. - """ - _defaults = collections.OrderedDict([ - ('ns', None), - ('name', None), - ('kind', DataPointType.measurement), - ('value', None), - ('count', None), - ('min', None), - ('max', None), - ('stdDev', None) - ]) - - def __init__(self): - """Initializes a new instance of the class. - """ - self._values = { - 'name': None, - 'kind': DataPointType.measurement, - 'value': None, - } - self._initialize() - - @property - def ns(self): - """The ns property. - - Returns: - (string). the property value. (defaults to: None) - """ - if 'ns' in self._values: - return self._values['ns'] - return self._defaults['ns'] - - @ns.setter - def ns(self, value): - """The ns property. - - Args: - value (string). the property value. - """ - if value == self._defaults['ns'] and 'ns' in self._values: - del self._values['ns'] - else: - self._values['ns'] = value - - @property - def name(self): - """The name property. - - Returns: - (string). the property value. (defaults to: None) - """ - return self._values['name'] - - @name.setter - def name(self, value): - """The name property. - - Args: - value (string). the property value. - """ - self._values['name'] = value - - @property - def kind(self): - """The kind property. - - Returns: - (:class:`DataPointType.measurement`). the property value. (defaults to: DataPointType.measurement) - """ - if 'kind' in self._values: - return self._values['kind'] - return self._defaults['kind'] - - @kind.setter - def kind(self, value): - """The kind property. - - Args: - value (:class:`DataPointType.measurement`). the property value. - """ - if value == self._defaults['kind'] and 'kind' in self._values: - del self._values['kind'] - else: - self._values['kind'] = value - - @property - def value(self): - """The value property. - - Returns: - (float). the property value. (defaults to: None) - """ - return self._values['value'] - - @value.setter - def value(self, value): - """The value property. - - Args: - value (float). the property value. - """ - self._values['value'] = value - - @property - def count(self): - """The count property. - - Returns: - (int). the property value. (defaults to: None) - """ - if 'count' in self._values: - return self._values['count'] - return self._defaults['count'] - - @count.setter - def count(self, value): - """The count property. - - Args: - value (int). the property value. - """ - if value == self._defaults['count'] and 'count' in self._values: - del self._values['count'] - else: - self._values['count'] = value - - @property - def min(self): - """The min property. - - Returns: - (float). the property value. (defaults to: None) - """ - if 'min' in self._values: - return self._values['min'] - return self._defaults['min'] - - @min.setter - def min(self, value): - """The min property. - - Args: - value (float). the property value. - """ - if value == self._defaults['min'] and 'min' in self._values: - del self._values['min'] - else: - self._values['min'] = value - - @property - def max(self): - """The max property. - - Returns: - (float). the property value. (defaults to: None) - """ - if 'max' in self._values: - return self._values['max'] - return self._defaults['max'] - - @max.setter - def max(self, value): - """The max property. - - Args: - value (float). the property value. - """ - if value == self._defaults['max'] and 'max' in self._values: - del self._values['max'] - else: - self._values['max'] = value - - @property - def std_dev(self): - """The std_dev property. - - Returns: - (float). the property value. (defaults to: None) - """ - if 'stdDev' in self._values: - return self._values['stdDev'] - return self._defaults['stdDev'] - - @std_dev.setter - def std_dev(self, value): - """The std_dev property. - - Args: - value (float). the property value. - """ - if value == self._defaults['stdDev'] and 'stdDev' in self._values: - del self._values['stdDev'] - else: - self._values['stdDev'] = value - - def _initialize(self): - """Initializes the current instance of the object. - """ - pass - - def write(self): - """Writes the contents of this object and returns the content as a dict object. - - Returns: - (dict). the object that represents the same data as the current instance. - """ - return _write_complex_object(self._defaults, self._values) - diff --git a/applicationinsights/channel/contracts/DataPointType.py b/applicationinsights/channel/contracts/DataPointType.py deleted file mode 100644 index e0d95ae7..00000000 --- a/applicationinsights/channel/contracts/DataPointType.py +++ /dev/null @@ -1,9 +0,0 @@ -class DataPointType(object): - """Data contract class for type DataPointType.""" - # Enumeration value measurement - measurement = 0 - - # Enumeration value aggregation - aggregation = 1 - - diff --git a/applicationinsights/channel/contracts/Device.py b/applicationinsights/channel/contracts/Device.py deleted file mode 100644 index e1df76ed..00000000 --- a/applicationinsights/channel/contracts/Device.py +++ /dev/null @@ -1,174 +0,0 @@ -import collections -import copy -from .Utils import _write_complex_object - -class Device(object): - """Data contract class for type Device. - """ - _defaults = collections.OrderedDict([ - ('ai.device.id', None), - ('ai.device.locale', None), - ('ai.device.model', None), - ('ai.device.oemName', None), - ('ai.device.osVersion', None), - ('ai.device.type', None) - ]) - - def __init__(self): - """Initializes a new instance of the class. - """ - self._values = { - } - self._initialize() - - @property - def id(self): - """The id property. - - Returns: - (string). the property value. (defaults to: None) - """ - if 'ai.device.id' in self._values: - return self._values['ai.device.id'] - return self._defaults['ai.device.id'] - - @id.setter - def id(self, value): - """The id property. - - Args: - value (string). the property value. - """ - if value == self._defaults['ai.device.id'] and 'ai.device.id' in self._values: - del self._values['ai.device.id'] - else: - self._values['ai.device.id'] = value - - @property - def locale(self): - """The locale property. - - Returns: - (string). the property value. (defaults to: None) - """ - if 'ai.device.locale' in self._values: - return self._values['ai.device.locale'] - return self._defaults['ai.device.locale'] - - @locale.setter - def locale(self, value): - """The locale property. - - Args: - value (string). the property value. - """ - if value == self._defaults['ai.device.locale'] and 'ai.device.locale' in self._values: - del self._values['ai.device.locale'] - else: - self._values['ai.device.locale'] = value - - @property - def model(self): - """The model property. - - Returns: - (string). the property value. (defaults to: None) - """ - if 'ai.device.model' in self._values: - return self._values['ai.device.model'] - return self._defaults['ai.device.model'] - - @model.setter - def model(self, value): - """The model property. - - Args: - value (string). the property value. - """ - if value == self._defaults['ai.device.model'] and 'ai.device.model' in self._values: - del self._values['ai.device.model'] - else: - self._values['ai.device.model'] = value - - @property - def oem_name(self): - """The oem_name property. - - Returns: - (string). the property value. (defaults to: None) - """ - if 'ai.device.oemName' in self._values: - return self._values['ai.device.oemName'] - return self._defaults['ai.device.oemName'] - - @oem_name.setter - def oem_name(self, value): - """The oem_name property. - - Args: - value (string). the property value. - """ - if value == self._defaults['ai.device.oemName'] and 'ai.device.oemName' in self._values: - del self._values['ai.device.oemName'] - else: - self._values['ai.device.oemName'] = value - - @property - def os_version(self): - """The os_version property. - - Returns: - (string). the property value. (defaults to: None) - """ - if 'ai.device.osVersion' in self._values: - return self._values['ai.device.osVersion'] - return self._defaults['ai.device.osVersion'] - - @os_version.setter - def os_version(self, value): - """The os_version property. - - Args: - value (string). the property value. - """ - if value == self._defaults['ai.device.osVersion'] and 'ai.device.osVersion' in self._values: - del self._values['ai.device.osVersion'] - else: - self._values['ai.device.osVersion'] = value - - @property - def type(self): - """The type property. - - Returns: - (string). the property value. (defaults to: None) - """ - if 'ai.device.type' in self._values: - return self._values['ai.device.type'] - return self._defaults['ai.device.type'] - - @type.setter - def type(self, value): - """The type property. - - Args: - value (string). the property value. - """ - if value == self._defaults['ai.device.type'] and 'ai.device.type' in self._values: - del self._values['ai.device.type'] - else: - self._values['ai.device.type'] = value - - def _initialize(self): - """Initializes the current instance of the object. - """ - pass - - def write(self): - """Writes the contents of this object and returns the content as a dict object. - - Returns: - (dict). the object that represents the same data as the current instance. - """ - return _write_complex_object(self._defaults, self._values) - diff --git a/applicationinsights/channel/contracts/Domain.py b/applicationinsights/channel/contracts/Domain.py deleted file mode 100644 index fb026029..00000000 --- a/applicationinsights/channel/contracts/Domain.py +++ /dev/null @@ -1,30 +0,0 @@ -import collections -import copy -from .Utils import _write_complex_object - -class Domain(object): - """Data contract class for type Domain. - """ - _defaults = collections.OrderedDict([ - ]) - - def __init__(self): - """Initializes a new instance of the class. - """ - self._values = { - } - self._initialize() - - def _initialize(self): - """Initializes the current instance of the object. - """ - pass - - def write(self): - """Writes the contents of this object and returns the content as a dict object. - - Returns: - (dict). the object that represents the same data as the current instance. - """ - return _write_complex_object(self._defaults, self._values) - diff --git a/applicationinsights/channel/contracts/Envelope.py b/applicationinsights/channel/contracts/Envelope.py deleted file mode 100644 index c9961988..00000000 --- a/applicationinsights/channel/contracts/Envelope.py +++ /dev/null @@ -1,217 +0,0 @@ -import collections -import copy -from .Utils import _write_complex_object - -class Envelope(object): - """Data contract class for type Envelope. - """ - _defaults = collections.OrderedDict([ - ('ver', 1), - ('name', None), - ('time', None), - ('sampleRate', 100.0), - ('seq', None), - ('iKey', None), - ('tags', {}), - ('data', None) - ]) - - def __init__(self): - """Initializes a new instance of the class. - """ - self._values = { - 'ver': 1, - 'name': None, - 'time': None, - 'sampleRate': 100.0, - } - self._initialize() - - @property - def ver(self): - """The ver property. - - Returns: - (int). the property value. (defaults to: 1) - """ - if 'ver' in self._values: - return self._values['ver'] - return self._defaults['ver'] - - @ver.setter - def ver(self, value): - """The ver property. - - Args: - value (int). the property value. - """ - if value == self._defaults['ver'] and 'ver' in self._values: - del self._values['ver'] - else: - self._values['ver'] = value - - @property - def name(self): - """The name property. - - Returns: - (string). the property value. (defaults to: None) - """ - return self._values['name'] - - @name.setter - def name(self, value): - """The name property. - - Args: - value (string). the property value. - """ - self._values['name'] = value - - @property - def time(self): - """The time property. - - Returns: - (string). the property value. (defaults to: None) - """ - return self._values['time'] - - @time.setter - def time(self, value): - """The time property. - - Args: - value (string). the property value. - """ - self._values['time'] = value - - @property - def sample_rate(self): - """The sample_rate property. - - Returns: - (float). the property value. (defaults to: 100.0) - """ - if 'sampleRate' in self._values: - return self._values['sampleRate'] - return self._defaults['sampleRate'] - - @sample_rate.setter - def sample_rate(self, value): - """The sample_rate property. - - Args: - value (float). the property value. - """ - if value == self._defaults['sampleRate'] and 'sampleRate' in self._values: - del self._values['sampleRate'] - else: - self._values['sampleRate'] = value - - @property - def seq(self): - """The seq property. - - Returns: - (string). the property value. (defaults to: None) - """ - if 'seq' in self._values: - return self._values['seq'] - return self._defaults['seq'] - - @seq.setter - def seq(self, value): - """The seq property. - - Args: - value (string). the property value. - """ - if value == self._defaults['seq'] and 'seq' in self._values: - del self._values['seq'] - else: - self._values['seq'] = value - - @property - def ikey(self): - """The ikey property. - - Returns: - (string). the property value. (defaults to: None) - """ - if 'iKey' in self._values: - return self._values['iKey'] - return self._defaults['iKey'] - - @ikey.setter - def ikey(self, value): - """The ikey property. - - Args: - value (string). the property value. - """ - if value == self._defaults['iKey'] and 'iKey' in self._values: - del self._values['iKey'] - else: - self._values['iKey'] = value - - @property - def tags(self): - """The tags property. - - Returns: - (hash). the property value. (defaults to: {}) - """ - if 'tags' in self._values: - return self._values['tags'] - self._values['tags'] = copy.deepcopy(self._defaults['tags']) - return self._values['tags'] - - @tags.setter - def tags(self, value): - """The tags property. - - Args: - value (hash). the property value. - """ - if value == self._defaults['tags'] and 'tags' in self._values: - del self._values['tags'] - else: - self._values['tags'] = value - - @property - def data(self): - """The data property. - - Returns: - (object). the property value. (defaults to: None) - """ - if 'data' in self._values: - return self._values['data'] - return self._defaults['data'] - - @data.setter - def data(self, value): - """The data property. - - Args: - value (object). the property value. - """ - if value == self._defaults['data'] and 'data' in self._values: - del self._values['data'] - else: - self._values['data'] = value - - def _initialize(self): - """Initializes the current instance of the object. - """ - pass - - def write(self): - """Writes the contents of this object and returns the content as a dict object. - - Returns: - (dict). the object that represents the same data as the current instance. - """ - return _write_complex_object(self._defaults, self._values) - diff --git a/applicationinsights/channel/contracts/EventData.py b/applicationinsights/channel/contracts/EventData.py deleted file mode 100644 index f588fa12..00000000 --- a/applicationinsights/channel/contracts/EventData.py +++ /dev/null @@ -1,125 +0,0 @@ -import collections -import copy -from .Utils import _write_complex_object - -class EventData(object): - """Data contract class for type EventData. - """ - - ENVELOPE_TYPE_NAME = 'Microsoft.ApplicationInsights.Event' - - DATA_TYPE_NAME = 'EventData' - - _defaults = collections.OrderedDict([ - ('ver', 2), - ('name', None), - ('properties', {}), - ('measurements', {}) - ]) - - def __init__(self): - """Initializes a new instance of the class. - """ - self._values = { - 'ver': 2, - 'name': None, - } - self._initialize() - - @property - def ver(self): - """The ver property. - - Returns: - (int). the property value. (defaults to: 2) - """ - return self._values['ver'] - - @ver.setter - def ver(self, value): - """The ver property. - - Args: - value (int). the property value. - """ - self._values['ver'] = value - - @property - def name(self): - """The name property. - - Returns: - (string). the property value. (defaults to: None) - """ - return self._values['name'] - - @name.setter - def name(self, value): - """The name property. - - Args: - value (string). the property value. - """ - self._values['name'] = value - - @property - def properties(self): - """The properties property. - - Returns: - (hash). the property value. (defaults to: {}) - """ - if 'properties' in self._values: - return self._values['properties'] - self._values['properties'] = copy.deepcopy(self._defaults['properties']) - return self._values['properties'] - - @properties.setter - def properties(self, value): - """The properties property. - - Args: - value (hash). the property value. - """ - if value == self._defaults['properties'] and 'properties' in self._values: - del self._values['properties'] - else: - self._values['properties'] = value - - @property - def measurements(self): - """The measurements property. - - Returns: - (hash). the property value. (defaults to: {}) - """ - if 'measurements' in self._values: - return self._values['measurements'] - self._values['measurements'] = copy.deepcopy(self._defaults['measurements']) - return self._values['measurements'] - - @measurements.setter - def measurements(self, value): - """The measurements property. - - Args: - value (hash). the property value. - """ - if value == self._defaults['measurements'] and 'measurements' in self._values: - del self._values['measurements'] - else: - self._values['measurements'] = value - - def _initialize(self): - """Initializes the current instance of the object. - """ - pass - - def write(self): - """Writes the contents of this object and returns the content as a dict object. - - Returns: - (dict). the object that represents the same data as the current instance. - """ - return _write_complex_object(self._defaults, self._values) - diff --git a/applicationinsights/channel/contracts/ExceptionData.py b/applicationinsights/channel/contracts/ExceptionData.py deleted file mode 100644 index 63310191..00000000 --- a/applicationinsights/channel/contracts/ExceptionData.py +++ /dev/null @@ -1,173 +0,0 @@ -import collections -import copy -from .Utils import _write_complex_object - -class ExceptionData(object): - """Data contract class for type ExceptionData. - """ - - ENVELOPE_TYPE_NAME = 'Microsoft.ApplicationInsights.Exception' - - DATA_TYPE_NAME = 'ExceptionData' - - _defaults = collections.OrderedDict([ - ('ver', 2), - ('exceptions', []), - ('severityLevel', None), - ('problemId', None), - ('properties', {}), - ('measurements', {}) - ]) - - def __init__(self): - """Initializes a new instance of the class. - """ - self._values = { - 'ver': 2, - 'exceptions': [], - } - self._initialize() - - @property - def ver(self): - """The ver property. - - Returns: - (int). the property value. (defaults to: 2) - """ - return self._values['ver'] - - @ver.setter - def ver(self, value): - """The ver property. - - Args: - value (int). the property value. - """ - self._values['ver'] = value - - @property - def exceptions(self): - """The exceptions property. - - Returns: - (list). the property value. (defaults to: []) - """ - return self._values['exceptions'] - - @exceptions.setter - def exceptions(self, value): - """The exceptions property. - - Args: - value (list). the property value. - """ - self._values['exceptions'] = value - - @property - def severity_level(self): - """The severity_level property. - - Returns: - (int). the property value. (defaults to: None) - """ - if 'severityLevel' in self._values: - return self._values['severityLevel'] - return self._defaults['severityLevel'] - - @severity_level.setter - def severity_level(self, value): - """The severity_level property. - - Args: - value (int). the property value. - """ - if value == self._defaults['severityLevel'] and 'severityLevel' in self._values: - del self._values['severityLevel'] - else: - self._values['severityLevel'] = value - - @property - def problem_id(self): - """The problem_id property. - - Returns: - (string). the property value. (defaults to: None) - """ - if 'problemId' in self._values: - return self._values['problemId'] - return self._defaults['problemId'] - - @problem_id.setter - def problem_id(self, value): - """The problem_id property. - - Args: - value (string). the property value. - """ - if value == self._defaults['problemId'] and 'problemId' in self._values: - del self._values['problemId'] - else: - self._values['problemId'] = value - - @property - def properties(self): - """The properties property. - - Returns: - (hash). the property value. (defaults to: {}) - """ - if 'properties' in self._values: - return self._values['properties'] - self._values['properties'] = copy.deepcopy(self._defaults['properties']) - return self._values['properties'] - - @properties.setter - def properties(self, value): - """The properties property. - - Args: - value (hash). the property value. - """ - if value == self._defaults['properties'] and 'properties' in self._values: - del self._values['properties'] - else: - self._values['properties'] = value - - @property - def measurements(self): - """The measurements property. - - Returns: - (hash). the property value. (defaults to: {}) - """ - if 'measurements' in self._values: - return self._values['measurements'] - self._values['measurements'] = copy.deepcopy(self._defaults['measurements']) - return self._values['measurements'] - - @measurements.setter - def measurements(self, value): - """The measurements property. - - Args: - value (hash). the property value. - """ - if value == self._defaults['measurements'] and 'measurements' in self._values: - del self._values['measurements'] - else: - self._values['measurements'] = value - - def _initialize(self): - """Initializes the current instance of the object. - """ - pass - - def write(self): - """Writes the contents of this object and returns the content as a dict object. - - Returns: - (dict). the object that represents the same data as the current instance. - """ - return _write_complex_object(self._defaults, self._values) - diff --git a/applicationinsights/channel/contracts/ExceptionDetails.py b/applicationinsights/channel/contracts/ExceptionDetails.py deleted file mode 100644 index 57b4eaeb..00000000 --- a/applicationinsights/channel/contracts/ExceptionDetails.py +++ /dev/null @@ -1,192 +0,0 @@ -import collections -import copy -from .Utils import _write_complex_object - -class ExceptionDetails(object): - """Data contract class for type ExceptionDetails. - """ - _defaults = collections.OrderedDict([ - ('id', None), - ('outerId', None), - ('typeName', None), - ('message', None), - ('hasFullStack', True), - ('stack', None), - ('parsedStack', []) - ]) - - def __init__(self): - """Initializes a new instance of the class. - """ - self._values = { - 'typeName': None, - 'message': None, - 'hasFullStack': True, - } - self._initialize() - - @property - def id(self): - """The id property. - - Returns: - (int). the property value. (defaults to: None) - """ - if 'id' in self._values: - return self._values['id'] - return self._defaults['id'] - - @id.setter - def id(self, value): - """The id property. - - Args: - value (int). the property value. - """ - if value == self._defaults['id'] and 'id' in self._values: - del self._values['id'] - else: - self._values['id'] = value - - @property - def outer_id(self): - """The outer_id property. - - Returns: - (int). the property value. (defaults to: None) - """ - if 'outerId' in self._values: - return self._values['outerId'] - return self._defaults['outerId'] - - @outer_id.setter - def outer_id(self, value): - """The outer_id property. - - Args: - value (int). the property value. - """ - if value == self._defaults['outerId'] and 'outerId' in self._values: - del self._values['outerId'] - else: - self._values['outerId'] = value - - @property - def type_name(self): - """The type_name property. - - Returns: - (string). the property value. (defaults to: None) - """ - return self._values['typeName'] - - @type_name.setter - def type_name(self, value): - """The type_name property. - - Args: - value (string). the property value. - """ - self._values['typeName'] = value - - @property - def message(self): - """The message property. - - Returns: - (string). the property value. (defaults to: None) - """ - return self._values['message'] - - @message.setter - def message(self, value): - """The message property. - - Args: - value (string). the property value. - """ - self._values['message'] = value - - @property - def has_full_stack(self): - """The has_full_stack property. - - Returns: - (bool). the property value. (defaults to: True) - """ - if 'hasFullStack' in self._values: - return self._values['hasFullStack'] - return self._defaults['hasFullStack'] - - @has_full_stack.setter - def has_full_stack(self, value): - """The has_full_stack property. - - Args: - value (bool). the property value. - """ - if value == self._defaults['hasFullStack'] and 'hasFullStack' in self._values: - del self._values['hasFullStack'] - else: - self._values['hasFullStack'] = value - - @property - def stack(self): - """The stack property. - - Returns: - (string). the property value. (defaults to: None) - """ - if 'stack' in self._values: - return self._values['stack'] - return self._defaults['stack'] - - @stack.setter - def stack(self, value): - """The stack property. - - Args: - value (string). the property value. - """ - if value == self._defaults['stack'] and 'stack' in self._values: - del self._values['stack'] - else: - self._values['stack'] = value - - @property - def parsed_stack(self): - """The parsed_stack property. - - Returns: - (list). the property value. (defaults to: []) - """ - if 'parsedStack' in self._values: - return self._values['parsedStack'] - self._values['parsedStack'] = copy.deepcopy(self._defaults['parsedStack']) - return self._values['parsedStack'] - - @parsed_stack.setter - def parsed_stack(self, value): - """The parsed_stack property. - - Args: - value (list). the property value. - """ - if value == self._defaults['parsedStack'] and 'parsedStack' in self._values: - del self._values['parsedStack'] - else: - self._values['parsedStack'] = value - - def _initialize(self): - """Initializes the current instance of the object. - """ - pass - - def write(self): - """Writes the contents of this object and returns the content as a dict object. - - Returns: - (dict). the object that represents the same data as the current instance. - """ - return _write_complex_object(self._defaults, self._values) - diff --git a/applicationinsights/channel/contracts/Internal.py b/applicationinsights/channel/contracts/Internal.py deleted file mode 100644 index ea005eb5..00000000 --- a/applicationinsights/channel/contracts/Internal.py +++ /dev/null @@ -1,102 +0,0 @@ -import collections -import copy -from .Utils import _write_complex_object - -class Internal(object): - """Data contract class for type Internal. - """ - _defaults = collections.OrderedDict([ - ('ai.internal.sdkVersion', None), - ('ai.internal.agentVersion', None), - ('ai.internal.nodeName', None) - ]) - - def __init__(self): - """Initializes a new instance of the class. - """ - self._values = { - } - self._initialize() - - @property - def sdk_version(self): - """The sdk_version property. - - Returns: - (string). the property value. (defaults to: None) - """ - if 'ai.internal.sdkVersion' in self._values: - return self._values['ai.internal.sdkVersion'] - return self._defaults['ai.internal.sdkVersion'] - - @sdk_version.setter - def sdk_version(self, value): - """The sdk_version property. - - Args: - value (string). the property value. - """ - if value == self._defaults['ai.internal.sdkVersion'] and 'ai.internal.sdkVersion' in self._values: - del self._values['ai.internal.sdkVersion'] - else: - self._values['ai.internal.sdkVersion'] = value - - @property - def agent_version(self): - """The agent_version property. - - Returns: - (string). the property value. (defaults to: None) - """ - if 'ai.internal.agentVersion' in self._values: - return self._values['ai.internal.agentVersion'] - return self._defaults['ai.internal.agentVersion'] - - @agent_version.setter - def agent_version(self, value): - """The agent_version property. - - Args: - value (string). the property value. - """ - if value == self._defaults['ai.internal.agentVersion'] and 'ai.internal.agentVersion' in self._values: - del self._values['ai.internal.agentVersion'] - else: - self._values['ai.internal.agentVersion'] = value - - @property - def node_name(self): - """The node_name property. - - Returns: - (string). the property value. (defaults to: None) - """ - if 'ai.internal.nodeName' in self._values: - return self._values['ai.internal.nodeName'] - return self._defaults['ai.internal.nodeName'] - - @node_name.setter - def node_name(self, value): - """The node_name property. - - Args: - value (string). the property value. - """ - if value == self._defaults['ai.internal.nodeName'] and 'ai.internal.nodeName' in self._values: - del self._values['ai.internal.nodeName'] - else: - self._values['ai.internal.nodeName'] = value - - def _initialize(self): - """Initializes the current instance of the object. - """ - pass - - def write(self): - """Writes the contents of this object and returns the content as a dict object. - - Returns: - (dict). the object that represents the same data as the current instance. - """ - return _write_complex_object(self._defaults, self._values) - diff --git a/applicationinsights/channel/contracts/Location.py b/applicationinsights/channel/contracts/Location.py deleted file mode 100644 index a6cfba5d..00000000 --- a/applicationinsights/channel/contracts/Location.py +++ /dev/null @@ -1,54 +0,0 @@ -import collections -import copy -from .Utils import _write_complex_object - -class Location(object): - """Data contract class for type Location. - """ - _defaults = collections.OrderedDict([ - ('ai.location.ip', None) - ]) - - def __init__(self): - """Initializes a new instance of the class. - """ - self._values = { - } - self._initialize() - - @property - def ip(self): - """The ip property. - - Returns: - (string). the property value. (defaults to: None) - """ - if 'ai.location.ip' in self._values: - return self._values['ai.location.ip'] - return self._defaults['ai.location.ip'] - - @ip.setter - def ip(self, value): - """The ip property. - - Args: - value (string). the property value. - """ - if value == self._defaults['ai.location.ip'] and 'ai.location.ip' in self._values: - del self._values['ai.location.ip'] - else: - self._values['ai.location.ip'] = value - - def _initialize(self): - """Initializes the current instance of the object. - """ - pass - - def write(self): - """Writes the contents of this object and returns the content as a dict object. - - Returns: - (dict). the object that represents the same data as the current instance. - """ - return _write_complex_object(self._defaults, self._values) - diff --git a/applicationinsights/channel/contracts/MessageData.py b/applicationinsights/channel/contracts/MessageData.py deleted file mode 100644 index d3fcb95e..00000000 --- a/applicationinsights/channel/contracts/MessageData.py +++ /dev/null @@ -1,138 +0,0 @@ -import collections -import copy -import logging -from .Utils import _write_complex_object - -class MessageData(object): - """Data contract class for type MessageData. - """ - - ENVELOPE_TYPE_NAME = 'Microsoft.ApplicationInsights.Message' - - DATA_TYPE_NAME = 'MessageData' - - PYTHON_LOGGING_LEVELS = { - 'DEBUG': 0, - 'INFO': 1, - 'WARNING': 2, - 'ERROR': 3, - 'CRITICAL': 4, - logging.DEBUG: 0, - logging.INFO: 1, - logging.WARNING: 2, - logging.ERROR: 3, - logging.CRITICAL: 4 - } - - _defaults = collections.OrderedDict([ - ('ver', 2), - ('message', None), - ('severityLevel', None), - ('properties', {}) - ]) - - def __init__(self): - """Initializes a new instance of the class. - """ - self._values = { - 'ver': 2, - 'message': None, - } - self._initialize() - - @property - def ver(self): - """The ver property. - - Returns: - (int). the property value. (defaults to: 2) - """ - return self._values['ver'] - - @ver.setter - def ver(self, value): - """The ver property. - - Args: - value (int). the property value. - """ - self._values['ver'] = value - - @property - def message(self): - """The message property. - - Returns: - (string). the property value. (defaults to: None) - """ - return self._values['message'] - - @message.setter - def message(self, value): - """The message property. - - Args: - value (string). the property value. - """ - self._values['message'] = value - - @property - def severity_level(self): - """The severity_level property. - - Returns: - (int). the property value. (defaults to: None) - """ - if 'severityLevel' in self._values: - return self._values['severityLevel'] - return self._defaults['severityLevel'] - - @severity_level.setter - def severity_level(self, value): - """The severity_level property. - - Args: - value (int). the property value. - """ - if value == self._defaults['severityLevel'] and 'severityLevel' in self._values: - del self._values['severityLevel'] - else: - self._values['severityLevel'] = value - - @property - def properties(self): - """The properties property. - - Returns: - (hash). the property value. (defaults to: {}) - """ - if 'properties' in self._values: - return self._values['properties'] - self._values['properties'] = copy.deepcopy(self._defaults['properties']) - return self._values['properties'] - - @properties.setter - def properties(self, value): - """The properties property. - - Args: - value (hash). the property value. - """ - if value == self._defaults['properties'] and 'properties' in self._values: - del self._values['properties'] - else: - self._values['properties'] = value - - def _initialize(self): - """Initializes the current instance of the object. - """ - pass - - def write(self): - """Writes the contents of this object and returns the content as a dict object. - - Returns: - (dict). the object that represents the same data as the current instance. - """ - return _write_complex_object(self._defaults, self._values) - diff --git a/applicationinsights/channel/contracts/MetricData.py b/applicationinsights/channel/contracts/MetricData.py deleted file mode 100644 index 4371edea..00000000 --- a/applicationinsights/channel/contracts/MetricData.py +++ /dev/null @@ -1,100 +0,0 @@ -import collections -import copy -from .Utils import _write_complex_object - -class MetricData(object): - """Data contract class for type MetricData. - """ - - ENVELOPE_TYPE_NAME = 'Microsoft.ApplicationInsights.Metric' - - DATA_TYPE_NAME = 'MetricData' - - _defaults = collections.OrderedDict([ - ('ver', 2), - ('metrics', []), - ('properties', {}) - ]) - - def __init__(self): - """Initializes a new instance of the class. - """ - self._values = { - 'ver': 2, - 'metrics': [], - } - self._initialize() - - @property - def ver(self): - """The ver property. - - Returns: - (int). the property value. (defaults to: 2) - """ - return self._values['ver'] - - @ver.setter - def ver(self, value): - """The ver property. - - Args: - value (int). the property value. - """ - self._values['ver'] = value - - @property - def metrics(self): - """The metrics property. - - Returns: - (list). the property value. (defaults to: []) - """ - return self._values['metrics'] - - @metrics.setter - def metrics(self, value): - """The metrics property. - - Args: - value (list). the property value. - """ - self._values['metrics'] = value - - @property - def properties(self): - """The properties property. - - Returns: - (hash). the property value. (defaults to: {}) - """ - if 'properties' in self._values: - return self._values['properties'] - self._values['properties'] = copy.deepcopy(self._defaults['properties']) - return self._values['properties'] - - @properties.setter - def properties(self, value): - """The properties property. - - Args: - value (hash). the property value. - """ - if value == self._defaults['properties'] and 'properties' in self._values: - del self._values['properties'] - else: - self._values['properties'] = value - - def _initialize(self): - """Initializes the current instance of the object. - """ - pass - - def write(self): - """Writes the contents of this object and returns the content as a dict object. - - Returns: - (dict). the object that represents the same data as the current instance. - """ - return _write_complex_object(self._defaults, self._values) - diff --git a/applicationinsights/channel/contracts/Operation.py b/applicationinsights/channel/contracts/Operation.py deleted file mode 100644 index 0bb08169..00000000 --- a/applicationinsights/channel/contracts/Operation.py +++ /dev/null @@ -1,150 +0,0 @@ -import collections -import copy -from .Utils import _write_complex_object - -class Operation(object): - """Data contract class for type Operation. - """ - _defaults = collections.OrderedDict([ - ('ai.operation.id', None), - ('ai.operation.name', None), - ('ai.operation.parentId', None), - ('ai.operation.syntheticSource', None), - ('ai.operation.correlationVector', None) - ]) - - def __init__(self): - """Initializes a new instance of the class. - """ - self._values = { - } - self._initialize() - - @property - def id(self): - """The id property. - - Returns: - (string). the property value. (defaults to: None) - """ - if 'ai.operation.id' in self._values: - return self._values['ai.operation.id'] - return self._defaults['ai.operation.id'] - - @id.setter - def id(self, value): - """The id property. - - Args: - value (string). the property value. - """ - if value == self._defaults['ai.operation.id'] and 'ai.operation.id' in self._values: - del self._values['ai.operation.id'] - else: - self._values['ai.operation.id'] = value - - @property - def name(self): - """The name property. - - Returns: - (string). the property value. (defaults to: None) - """ - if 'ai.operation.name' in self._values: - return self._values['ai.operation.name'] - return self._defaults['ai.operation.name'] - - @name.setter - def name(self, value): - """The name property. - - Args: - value (string). the property value. - """ - if value == self._defaults['ai.operation.name'] and 'ai.operation.name' in self._values: - del self._values['ai.operation.name'] - else: - self._values['ai.operation.name'] = value - - @property - def parent_id(self): - """The parent_id property. - - Returns: - (string). the property value. (defaults to: None) - """ - if 'ai.operation.parentId' in self._values: - return self._values['ai.operation.parentId'] - return self._defaults['ai.operation.parentId'] - - @parent_id.setter - def parent_id(self, value): - """The parent_id property. - - Args: - value (string). the property value. - """ - if value == self._defaults['ai.operation.parentId'] and 'ai.operation.parentId' in self._values: - del self._values['ai.operation.parentId'] - else: - self._values['ai.operation.parentId'] = value - - @property - def synthetic_source(self): - """The synthetic_source property. - - Returns: - (string). the property value. (defaults to: None) - """ - if 'ai.operation.syntheticSource' in self._values: - return self._values['ai.operation.syntheticSource'] - return self._defaults['ai.operation.syntheticSource'] - - @synthetic_source.setter - def synthetic_source(self, value): - """The synthetic_source property. - - Args: - value (string). the property value. - """ - if value == self._defaults['ai.operation.syntheticSource'] and 'ai.operation.syntheticSource' in self._values: - del self._values['ai.operation.syntheticSource'] - else: - self._values['ai.operation.syntheticSource'] = value - - @property - def correlation_vector(self): - """The correlation_vector property. - - Returns: - (string). the property value. (defaults to: None) - """ - if 'ai.operation.correlationVector' in self._values: - return self._values['ai.operation.correlationVector'] - return self._defaults['ai.operation.correlationVector'] - - @correlation_vector.setter - def correlation_vector(self, value): - """The correlation_vector property. - - Args: - value (string). the property value. - """ - if value == self._defaults['ai.operation.correlationVector'] and 'ai.operation.correlationVector' in self._values: - del self._values['ai.operation.correlationVector'] - else: - self._values['ai.operation.correlationVector'] = value - - def _initialize(self): - """Initializes the current instance of the object. - """ - pass - - def write(self): - """Writes the contents of this object and returns the content as a dict object. - - Returns: - (dict). the object that represents the same data as the current instance. - """ - return _write_complex_object(self._defaults, self._values) - diff --git a/applicationinsights/channel/contracts/PageViewData.py b/applicationinsights/channel/contracts/PageViewData.py deleted file mode 100644 index dfe3d343..00000000 --- a/applicationinsights/channel/contracts/PageViewData.py +++ /dev/null @@ -1,220 +0,0 @@ -import collections -import copy -from .Utils import _write_complex_object - -class PageViewData(object): - """Data contract class for type PageViewData. - """ - ENVELOPE_TYPE_NAME = 'Microsoft.ApplicationInsights.PageView' - - DATA_TYPE_NAME = 'PageViewData' - - _defaults = collections.OrderedDict([ - ('ver', 2), - ('url', None), - ('name', None), - ('duration', None), - ('id', None), - ('referrerUri', None), - ('properties', {}), - ('measurements', {}) - ]) - - def __init__(self): - """Initializes a new instance of the class. - """ - self._values = { - 'ver': 2, - 'name': None, - } - self._initialize() - - @property - def ver(self): - """The ver property. - - Returns: - (int). the property value. (defaults to: 2) - """ - return self._values['ver'] - - @ver.setter - def ver(self, value): - """The ver property. - - Args: - value (int). the property value. - """ - self._values['ver'] = value - - @property - def url(self): - """The url property. - - Returns: - (string). the property value. (defaults to: None) - """ - if 'url' in self._values: - return self._values['url'] - return self._defaults['url'] - - @url.setter - def url(self, value): - """The url property. - - Args: - value (string). the property value. - """ - if value == self._defaults['url'] and 'url' in self._values: - del self._values['url'] - else: - self._values['url'] = value - - @property - def name(self): - """The name property. - - Returns: - (string). the property value. (defaults to: None) - """ - return self._values['name'] - - @name.setter - def name(self, value): - """The name property. - - Args: - value (string). the property value. - """ - self._values['name'] = value - - @property - def duration(self): - """The duration property. - - Returns: - (string). the property value. (defaults to: None) - """ - if 'duration' in self._values: - return self._values['duration'] - return self._defaults['duration'] - - @duration.setter - def duration(self, value): - """The duration property. - - Args: - value (string). the property value. - """ - if value == self._defaults['duration'] and 'duration' in self._values: - del self._values['duration'] - else: - self._values['duration'] = value - - @property - def id(self): - """The id property. - - Returns: - (string). the property value. (defaults to: None) - """ - if 'id' in self._values: - return self._values['id'] - return self._defaults['id'] - - @id.setter - def id(self, value): - """The id property. - - Args: - value (string). the property value. - """ - if value == self._defaults['id'] and 'id' in self._values: - del self._values['id'] - else: - self._values['id'] = value - - @property - def referrer_uri(self): - """The referrer_uri property. - - Returns: - (string). the property value. (defaults to: None) - """ - if 'referrerUri' in self._values: - return self._values['referrerUri'] - return self._defaults['referrerUri'] - - @referrer_uri.setter - def referrer_uri(self, value): - """The referrer_uri property. - - Args: - value (string). the property value. - """ - if value == self._defaults['referrerUri'] and 'referrerUri' in self._values: - del self._values['referrerUri'] - else: - self._values['referrerUri'] = value - - @property - def properties(self): - """The properties property. - - Returns: - (hash). the property value. (defaults to: {}) - """ - if 'properties' in self._values: - return self._values['properties'] - self._values['properties'] = copy.deepcopy(self._defaults['properties']) - return self._values['properties'] - - @properties.setter - def properties(self, value): - """The properties property. - - Args: - value (hash). the property value. - """ - if value == self._defaults['properties'] and 'properties' in self._values: - del self._values['properties'] - else: - self._values['properties'] = value - - @property - def measurements(self): - """The measurements property. - - Returns: - (hash). the property value. (defaults to: {}) - """ - if 'measurements' in self._values: - return self._values['measurements'] - self._values['measurements'] = copy.deepcopy(self._defaults['measurements']) - return self._values['measurements'] - - @measurements.setter - def measurements(self, value): - """The measurements property. - - Args: - value (hash). the property value. - """ - if value == self._defaults['measurements'] and 'measurements' in self._values: - del self._values['measurements'] - else: - self._values['measurements'] = value - - def _initialize(self): - """Initializes the current instance of the object. - """ - pass - - def write(self): - """Writes the contents of this object and returns the content as a dict object. - - Returns: - (dict). the object that represents the same data as the current instance. - """ - return _write_complex_object(self._defaults, self._values) - diff --git a/applicationinsights/channel/contracts/PageViewPerfData.py b/applicationinsights/channel/contracts/PageViewPerfData.py deleted file mode 100644 index 0dc6ac89..00000000 --- a/applicationinsights/channel/contracts/PageViewPerfData.py +++ /dev/null @@ -1,355 +0,0 @@ -import collections -import copy -from .Utils import _write_complex_object - -class PageViewPerfData(object): - """Data contract class for type PageViewPerfData. - """ - ENVELOPE_TYPE_NAME = 'Microsoft.ApplicationInsights.PageViewPerfData' - - DATA_TYPE_NAME = 'PageViewPerfData' - - _defaults = collections.OrderedDict([ - ('ver', 2), - ('ver', 2), - ('url', None), - ('perfTotal', None), - ('name', None), - ('name', None), - ('duration', None), - ('networkConnect', None), - ('sentRequest', None), - ('receivedResponse', None), - ('id', None), - ('domProcessing', None), - ('referrerUri', None), - ('properties', {}), - ('properties', {}), - ('measurements', {}), - ]) - - def __init__(self): - """Initializes a new instance of the class. - """ - self._values = { - 'ver': 2, - 'name': None, - } - self._initialize() - - @property - def ver(self): - """The ver property. - - Returns: - (int). the property value. (defaults to: 2) - """ - return self._values['ver'] - - @ver.setter - def ver(self, value): - """The ver property. - - Args: - value (int). the property value. - """ - self._values['ver'] = value - - @property - def url(self): - """The url property. - - Returns: - (string). the property value. (defaults to: None) - """ - if 'url' in self._values: - return self._values['url'] - return self._defaults['url'] - - @url.setter - def url(self, value): - """The url property. - - Args: - value (string). the property value. - """ - if value == self._defaults['url'] and 'url' in self._values: - del self._values['url'] - else: - self._values['url'] = value - - @property - def perf_total(self): - """The perf_total property. - - Returns: - (string). the property value. (defaults to: None) - """ - if 'perfTotal' in self._values: - return self._values['perfTotal'] - return self._defaults['perfTotal'] - - @perf_total.setter - def perf_total(self, value): - """The perf_total property. - - Args: - value (string). the property value. - """ - if value == self._defaults['perfTotal'] and 'perfTotal' in self._values: - del self._values['perfTotal'] - else: - self._values['perfTotal'] = value - - @property - def name(self): - """The name property. - - Returns: - (string). the property value. (defaults to: None) - """ - return self._values['name'] - - @name.setter - def name(self, value): - """The name property. - - Args: - value (string). the property value. - """ - self._values['name'] = value - - @property - def duration(self): - """The duration property. - - Returns: - (string). the property value. (defaults to: None) - """ - if 'duration' in self._values: - return self._values['duration'] - return self._defaults['duration'] - - @duration.setter - def duration(self, value): - """The duration property. - - Args: - value (string). the property value. - """ - if value == self._defaults['duration'] and 'duration' in self._values: - del self._values['duration'] - else: - self._values['duration'] = value - - @property - def network_connect(self): - """The network_connect property. - - Returns: - (string). the property value. (defaults to: None) - """ - if 'networkConnect' in self._values: - return self._values['networkConnect'] - return self._defaults['networkConnect'] - - @network_connect.setter - def network_connect(self, value): - """The network_connect property. - - Args: - value (string). the property value. - """ - if value == self._defaults['networkConnect'] and 'networkConnect' in self._values: - del self._values['networkConnect'] - else: - self._values['networkConnect'] = value - - @property - def sent_request(self): - """The sent_request property. - - Returns: - (string). the property value. (defaults to: None) - """ - if 'sentRequest' in self._values: - return self._values['sentRequest'] - return self._defaults['sentRequest'] - - @sent_request.setter - def sent_request(self, value): - """The sent_request property. - - Args: - value (string). the property value. - """ - if value == self._defaults['sentRequest'] and 'sentRequest' in self._values: - del self._values['sentRequest'] - else: - self._values['sentRequest'] = value - - @property - def received_response(self): - """The received_response property. - - Returns: - (string). the property value. (defaults to: None) - """ - if 'receivedResponse' in self._values: - return self._values['receivedResponse'] - return self._defaults['receivedResponse'] - - @received_response.setter - def received_response(self, value): - """The received_response property. - - Args: - value (string). the property value. - """ - if value == self._defaults['receivedResponse'] and 'receivedResponse' in self._values: - del self._values['receivedResponse'] - else: - self._values['receivedResponse'] = value - - @property - def id(self): - """The id property. - - Returns: - (string). the property value. (defaults to: None) - """ - if 'id' in self._values: - return self._values['id'] - return self._defaults['id'] - - @id.setter - def id(self, value): - """The id property. - - Args: - value (string). the property value. - """ - if value == self._defaults['id'] and 'id' in self._values: - del self._values['id'] - else: - self._values['id'] = value - - @property - def dom_processing(self): - """The dom_processing property. - - Returns: - (string). the property value. (defaults to: None) - """ - if 'domProcessing' in self._values: - return self._values['domProcessing'] - return self._defaults['domProcessing'] - - @dom_processing.setter - def dom_processing(self, value): - """The dom_processing property. - - Args: - value (string). the property value. - """ - if value == self._defaults['domProcessing'] and 'domProcessing' in self._values: - del self._values['domProcessing'] - else: - self._values['domProcessing'] = value - - @property - def referrer_uri(self): - """The referrer_uri property. - - Returns: - (string). the property value. (defaults to: None) - """ - if 'referrerUri' in self._values: - return self._values['referrerUri'] - return self._defaults['referrerUri'] - - @referrer_uri.setter - def referrer_uri(self, value): - """The referrer_uri property. - - Args: - value (string). the property value. - """ - if value == self._defaults['referrerUri'] and 'referrerUri' in self._values: - del self._values['referrerUri'] - else: - self._values['referrerUri'] = value - - @property - def properties(self): - """The properties property. - - Returns: - (hash). the property value. (defaults to: {}) - """ - if 'properties' in self._values: - return self._values['properties'] - self._values['properties'] = copy.deepcopy(self._defaults['properties']) - return self._values['properties'] - - @properties.setter - def properties(self, value): - """The properties property. - - Args: - value (hash). the property value. - """ - if value == self._defaults['properties'] and 'properties' in self._values: - del self._values['properties'] - else: - self._values['properties'] = value - - @property - def measurements(self): - """The measurements property. - - Returns: - (hash). the property value. (defaults to: {}) - """ - if 'measurements' in self._values: - return self._values['measurements'] - self._values['measurements'] = copy.deepcopy(self._defaults['measurements']) - return self._values['measurements'] - - @measurements.setter - def measurements(self, value): - """The measurements property. - - Args: - value (hash). the property value. - """ - if value == self._defaults['measurements'] and 'measurements' in self._values: - del self._values['measurements'] - else: - self._values['measurements'] = value - - @measurements.setter - def measurements(self, value): - """The measurements property. - - Args: - value (hash). the property value. - """ - if value == self._defaults['measurements'] and 'measurements' in self._values: - del self._values['measurements'] - else: - self._values['measurements'] = value - - def _initialize(self): - """Initializes the current instance of the object. - """ - pass - - def write(self): - """Writes the contents of this object and returns the content as a dict object. - - Returns: - (dict). the object that represents the same data as the current instance. - """ - return _write_complex_object(self._defaults, self._values) - diff --git a/applicationinsights/channel/contracts/RemoteDependencyData.py b/applicationinsights/channel/contracts/RemoteDependencyData.py deleted file mode 100644 index 15013a71..00000000 --- a/applicationinsights/channel/contracts/RemoteDependencyData.py +++ /dev/null @@ -1,289 +0,0 @@ -import collections -import copy -from .Utils import _write_complex_object - -class RemoteDependencyData(object): - """Data contract class for type RemoteDependencyData. - """ - ENVELOPE_TYPE_NAME = 'Microsoft.ApplicationInsights.RemoteDependency' - - DATA_TYPE_NAME = 'RemoteDependencyData' - - _defaults = collections.OrderedDict([ - ('ver', 2), - ('name', None), - ('id', None), - ('resultCode', None), - ('duration', None), - ('success', True), - ('data', None), - ('target', None), - ('type', None), - ('properties', {}), - ('measurements', {}) - ]) - - def __init__(self): - """Initializes a new instance of the class. - """ - self._values = { - 'ver': 2, - 'name': None, - 'duration': None, - 'success': True, - } - self._initialize() - - @property - def ver(self): - """The ver property. - - Returns: - (int). the property value. (defaults to: 2) - """ - return self._values['ver'] - - @ver.setter - def ver(self, value): - """The ver property. - - Args: - value (int). the property value. - """ - self._values['ver'] = value - - @property - def name(self): - """The name property. - - Returns: - (string). the property value. (defaults to: None) - """ - return self._values['name'] - - @name.setter - def name(self, value): - """The name property. - - Args: - value (string). the property value. - """ - self._values['name'] = value - - @property - def id(self): - """The id property. - - Returns: - (string). the property value. (defaults to: None) - """ - if 'id' in self._values: - return self._values['id'] - return self._defaults['id'] - - @id.setter - def id(self, value): - """The id property. - - Args: - value (string). the property value. - """ - if value == self._defaults['id'] and 'id' in self._values: - del self._values['id'] - else: - self._values['id'] = value - - @property - def result_code(self): - """The result_code property. - - Returns: - (string). the property value. (defaults to: None) - """ - if 'resultCode' in self._values: - return self._values['resultCode'] - return self._defaults['resultCode'] - - @result_code.setter - def result_code(self, value): - """The result_code property. - - Args: - value (string). the property value. - """ - if value == self._defaults['resultCode'] and 'resultCode' in self._values: - del self._values['resultCode'] - else: - self._values['resultCode'] = value - - @property - def duration(self): - """The duration property. - - Returns: - (string). the property value. (defaults to: None) - """ - return self._values['duration'] - - @duration.setter - def duration(self, value): - """The duration property. - - Args: - value (string). the property value. - """ - self._values['duration'] = value - - @property - def success(self): - """The success property. - - Returns: - (bool). the property value. (defaults to: True) - """ - if 'success' in self._values: - return self._values['success'] - return self._defaults['success'] - - @success.setter - def success(self, value): - """The success property. - - Args: - value (bool). the property value. - """ - if value == self._defaults['success'] and 'success' in self._values: - del self._values['success'] - else: - self._values['success'] = value - - @property - def data(self): - """The data property. - - Returns: - (string). the property value. (defaults to: None) - """ - if 'data' in self._values: - return self._values['data'] - return self._defaults['data'] - - @data.setter - def data(self, value): - """The data property. - - Args: - value (string). the property value. - """ - if value == self._defaults['data'] and 'data' in self._values: - del self._values['data'] - else: - self._values['data'] = value - - @property - def target(self): - """The target property. - - Returns: - (string). the property value. (defaults to: None) - """ - if 'target' in self._values: - return self._values['target'] - return self._defaults['target'] - - @target.setter - def target(self, value): - """The target property. - - Args: - value (string). the property value. - """ - if value == self._defaults['target'] and 'target' in self._values: - del self._values['target'] - else: - self._values['target'] = value - - @property - def type(self): - """The type property. - - Returns: - (string). the property value. (defaults to: None) - """ - if 'type' in self._values: - return self._values['type'] - return self._defaults['type'] - - @type.setter - def type(self, value): - """The type property. - - Args: - value (string). the property value. - """ - if value == self._defaults['type'] and 'type' in self._values: - del self._values['type'] - else: - self._values['type'] = value - - @property - def properties(self): - """The properties property. - - Returns: - (hash). the property value. (defaults to: {}) - """ - if 'properties' in self._values: - return self._values['properties'] - self._values['properties'] = copy.deepcopy(self._defaults['properties']) - return self._values['properties'] - - @properties.setter - def properties(self, value): - """The properties property. - - Args: - value (hash). the property value. - """ - if value == self._defaults['properties'] and 'properties' in self._values: - del self._values['properties'] - else: - self._values['properties'] = value - - @property - def measurements(self): - """The measurements property. - - Returns: - (hash). the property value. (defaults to: {}) - """ - if 'measurements' in self._values: - return self._values['measurements'] - self._values['measurements'] = copy.deepcopy(self._defaults['measurements']) - return self._values['measurements'] - - @measurements.setter - def measurements(self, value): - """The measurements property. - - Args: - value (hash). the property value. - """ - if value == self._defaults['measurements'] and 'measurements' in self._values: - del self._values['measurements'] - else: - self._values['measurements'] = value - - def _initialize(self): - """Initializes the current instance of the object. - """ - pass - - def write(self): - """Writes the contents of this object and returns the content as a dict object. - - Returns: - (dict). the object that represents the same data as the current instance. - """ - return _write_complex_object(self._defaults, self._values) - diff --git a/applicationinsights/channel/contracts/RequestData.py b/applicationinsights/channel/contracts/RequestData.py deleted file mode 100644 index 395eb16f..00000000 --- a/applicationinsights/channel/contracts/RequestData.py +++ /dev/null @@ -1,256 +0,0 @@ -import collections -import copy -from .Utils import _write_complex_object - -class RequestData(object): - """Data contract class for type RequestData. - """ - ENVELOPE_TYPE_NAME = 'Microsoft.ApplicationInsights.Request' - - DATA_TYPE_NAME = 'RequestData' - - _defaults = collections.OrderedDict([ - ('ver', 2), - ('id', None), - ('source', None), - ('name', None), - ('duration', None), - ('responseCode', None), - ('success', None), - ('url', None), - ('properties', {}), - ('measurements', {}) - ]) - - def __init__(self): - """Initializes a new instance of the class. - """ - self._values = { - 'ver': 2, - 'id': None, - 'duration': None, - 'responseCode': None, - 'success': None, - } - self._initialize() - - @property - def ver(self): - """The ver property. - - Returns: - (int). the property value. (defaults to: 2) - """ - return self._values['ver'] - - @ver.setter - def ver(self, value): - """The ver property. - - Args: - value (int). the property value. - """ - self._values['ver'] = value - - @property - def id(self): - """The id property. - - Returns: - (string). the property value. (defaults to: None) - """ - return self._values['id'] - - @id.setter - def id(self, value): - """The id property. - - Args: - value (string). the property value. - """ - self._values['id'] = value - - @property - def source(self): - """The source property. - - Returns: - (string). the property value. (defaults to: None) - """ - if 'source' in self._values: - return self._values['source'] - return self._defaults['source'] - - @source.setter - def source(self, value): - """The source property. - - Args: - value (string). the property value. - """ - if value == self._defaults['source'] and 'source' in self._values: - del self._values['source'] - else: - self._values['source'] = value - - @property - def name(self): - """The name property. - - Returns: - (string). the property value. (defaults to: None) - """ - if 'name' in self._values: - return self._values['name'] - return self._defaults['name'] - - @name.setter - def name(self, value): - """The name property. - - Args: - value (string). the property value. - """ - if value == self._defaults['name'] and 'name' in self._values: - del self._values['name'] - else: - self._values['name'] = value - - @property - def duration(self): - """The duration property. - - Returns: - (string). the property value. (defaults to: None) - """ - return self._values['duration'] - - @duration.setter - def duration(self, value): - """The duration property. - - Args: - value (string). the property value. - """ - self._values['duration'] = value - - @property - def response_code(self): - """The response_code property. - - Returns: - (string). the property value. (defaults to: None) - """ - return self._values['responseCode'] - - @response_code.setter - def response_code(self, value): - """The response_code property. - - Args: - value (string). the property value. - """ - self._values['responseCode'] = value - - @property - def success(self): - """The success property. - - Returns: - (bool). the property value. (defaults to: None) - """ - return self._values['success'] - - @success.setter - def success(self, value): - """The success property. - - Args: - value (bool). the property value. - """ - self._values['success'] = value - - @property - def url(self): - """The url property. - - Returns: - (string). the property value. (defaults to: None) - """ - if 'url' in self._values: - return self._values['url'] - return self._defaults['url'] - - @url.setter - def url(self, value): - """The url property. - - Args: - value (string). the property value. - """ - if value == self._defaults['url'] and 'url' in self._values: - del self._values['url'] - else: - self._values['url'] = value - - @property - def properties(self): - """The properties property. - - Returns: - (hash). the property value. (defaults to: {}) - """ - if 'properties' in self._values: - return self._values['properties'] - self._values['properties'] = copy.deepcopy(self._defaults['properties']) - return self._values['properties'] - - @properties.setter - def properties(self, value): - """The properties property. - - Args: - value (hash). the property value. - """ - if value == self._defaults['properties'] and 'properties' in self._values: - del self._values['properties'] - else: - self._values['properties'] = value - - @property - def measurements(self): - """The measurements property. - - Returns: - (hash). the property value. (defaults to: {}) - """ - if 'measurements' in self._values: - return self._values['measurements'] - self._values['measurements'] = copy.deepcopy(self._defaults['measurements']) - return self._values['measurements'] - - @measurements.setter - def measurements(self, value): - """The measurements property. - - Args: - value (hash). the property value. - """ - if value == self._defaults['measurements'] and 'measurements' in self._values: - del self._values['measurements'] - else: - self._values['measurements'] = value - - def _initialize(self): - """Initializes the current instance of the object. - """ - pass - - def write(self): - """Writes the contents of this object and returns the content as a dict object. - - Returns: - (dict). the object that represents the same data as the current instance. - """ - return _write_complex_object(self._defaults, self._values) - diff --git a/applicationinsights/channel/contracts/Session.py b/applicationinsights/channel/contracts/Session.py deleted file mode 100644 index 35a22f0b..00000000 --- a/applicationinsights/channel/contracts/Session.py +++ /dev/null @@ -1,78 +0,0 @@ -import collections -import copy -from .Utils import _write_complex_object - -class Session(object): - """Data contract class for type Session. - """ - _defaults = collections.OrderedDict([ - ('ai.session.id', None), - ('ai.session.isFirst', None) - ]) - - def __init__(self): - """Initializes a new instance of the class. - """ - self._values = { - } - self._initialize() - - @property - def id(self): - """The id property. - - Returns: - (string). the property value. (defaults to: None) - """ - if 'ai.session.id' in self._values: - return self._values['ai.session.id'] - return self._defaults['ai.session.id'] - - @id.setter - def id(self, value): - """The id property. - - Args: - value (string). the property value. - """ - if value == self._defaults['ai.session.id'] and 'ai.session.id' in self._values: - del self._values['ai.session.id'] - else: - self._values['ai.session.id'] = value - - @property - def is_first(self): - """The is_first property. - - Returns: - (string). the property value. (defaults to: None) - """ - if 'ai.session.isFirst' in self._values: - return self._values['ai.session.isFirst'] - return self._defaults['ai.session.isFirst'] - - @is_first.setter - def is_first(self, value): - """The is_first property. - - Args: - value (string). the property value. - """ - if value == self._defaults['ai.session.isFirst'] and 'ai.session.isFirst' in self._values: - del self._values['ai.session.isFirst'] - else: - self._values['ai.session.isFirst'] = value - - def _initialize(self): - """Initializes the current instance of the object. - """ - pass - - def write(self): - """Writes the contents of this object and returns the content as a dict object. - - Returns: - (dict). the object that represents the same data as the current instance. - """ - return _write_complex_object(self._defaults, self._values) - diff --git a/applicationinsights/channel/contracts/SeverityLevel.py b/applicationinsights/channel/contracts/SeverityLevel.py deleted file mode 100644 index be9a99ac..00000000 --- a/applicationinsights/channel/contracts/SeverityLevel.py +++ /dev/null @@ -1,18 +0,0 @@ -class SeverityLevel(object): - """Data contract class for type SeverityLevel.""" - # Enumeration value verbose - verbose = 0 - - # Enumeration value information - information = 1 - - # Enumeration value warning - warning = 2 - - # Enumeration value error - error = 3 - - # Enumeration value critical - critical = 4 - - diff --git a/applicationinsights/channel/contracts/StackFrame.py b/applicationinsights/channel/contracts/StackFrame.py deleted file mode 100644 index d7d834c6..00000000 --- a/applicationinsights/channel/contracts/StackFrame.py +++ /dev/null @@ -1,142 +0,0 @@ -import collections -import copy -from .Utils import _write_complex_object - -class StackFrame(object): - """Data contract class for type StackFrame. - """ - _defaults = collections.OrderedDict([ - ('level', None), - ('method', None), - ('assembly', None), - ('fileName', None), - ('line', None) - ]) - - def __init__(self): - """Initializes a new instance of the class. - """ - self._values = { - 'level': None, - 'method': None, - } - self._initialize() - - @property - def level(self): - """The level property. - - Returns: - (int). the property value. (defaults to: None) - """ - return self._values['level'] - - @level.setter - def level(self, value): - """The level property. - - Args: - value (int). the property value. - """ - self._values['level'] = value - - @property - def method(self): - """The method property. - - Returns: - (string). the property value. (defaults to: None) - """ - return self._values['method'] - - @method.setter - def method(self, value): - """The method property. - - Args: - value (string). the property value. - """ - self._values['method'] = value - - @property - def assembly(self): - """The assembly property. - - Returns: - (string). the property value. (defaults to: None) - """ - if 'assembly' in self._values: - return self._values['assembly'] - return self._defaults['assembly'] - - @assembly.setter - def assembly(self, value): - """The assembly property. - - Args: - value (string). the property value. - """ - if value == self._defaults['assembly'] and 'assembly' in self._values: - del self._values['assembly'] - else: - self._values['assembly'] = value - - @property - def file_name(self): - """The file_name property. - - Returns: - (string). the property value. (defaults to: None) - """ - if 'fileName' in self._values: - return self._values['fileName'] - return self._defaults['fileName'] - - @file_name.setter - def file_name(self, value): - """The file_name property. - - Args: - value (string). the property value. - """ - if value == self._defaults['fileName'] and 'fileName' in self._values: - del self._values['fileName'] - else: - self._values['fileName'] = value - - @property - def line(self): - """The line property. - - Returns: - (int). the property value. (defaults to: None) - """ - if 'line' in self._values: - return self._values['line'] - return self._defaults['line'] - - @line.setter - def line(self, value): - """The line property. - - Args: - value (int). the property value. - """ - if value == self._defaults['line'] and 'line' in self._values: - del self._values['line'] - else: - self._values['line'] = value - - def _initialize(self): - """Initializes the current instance of the object. - """ - pass - - def write(self): - """Writes the contents of this object and returns the content as a dict object. - - Returns: - (dict). the object that represents the same data as the current instance. - """ - return _write_complex_object(self._defaults, self._values) - diff --git a/applicationinsights/channel/contracts/User.py b/applicationinsights/channel/contracts/User.py deleted file mode 100644 index 55f6d429..00000000 --- a/applicationinsights/channel/contracts/User.py +++ /dev/null @@ -1,102 +0,0 @@ -import collections -import copy -from .Utils import _write_complex_object - -class User(object): - """Data contract class for type User. - """ - _defaults = collections.OrderedDict([ - ('ai.user.accountId', None), - ('ai.user.id', None), - ('ai.user.authUserId', None) - ]) - - def __init__(self): - """Initializes a new instance of the class. - """ - self._values = { - } - self._initialize() - - @property - def account_id(self): - """The account_id property. - - Returns: - (string). the property value. (defaults to: None) - """ - if 'ai.user.accountId' in self._values: - return self._values['ai.user.accountId'] - return self._defaults['ai.user.accountId'] - - @account_id.setter - def account_id(self, value): - """The account_id property. - - Args: - value (string). the property value. - """ - if value == self._defaults['ai.user.accountId'] and 'ai.user.accountId' in self._values: - del self._values['ai.user.accountId'] - else: - self._values['ai.user.accountId'] = value - - @property - def id(self): - """The id property. - - Returns: - (string). the property value. (defaults to: None) - """ - if 'ai.user.id' in self._values: - return self._values['ai.user.id'] - return self._defaults['ai.user.id'] - - @id.setter - def id(self, value): - """The id property. - - Args: - value (string). the property value. - """ - if value == self._defaults['ai.user.id'] and 'ai.user.id' in self._values: - del self._values['ai.user.id'] - else: - self._values['ai.user.id'] = value - - @property - def auth_user_id(self): - """The auth_user_id property. - - Returns: - (string). the property value. (defaults to: None) - """ - if 'ai.user.authUserId' in self._values: - return self._values['ai.user.authUserId'] - return self._defaults['ai.user.authUserId'] - - @auth_user_id.setter - def auth_user_id(self, value): - """The auth_user_id property. - - Args: - value (string). the property value. - """ - if value == self._defaults['ai.user.authUserId'] and 'ai.user.authUserId' in self._values: - del self._values['ai.user.authUserId'] - else: - self._values['ai.user.authUserId'] = value - - def _initialize(self): - """Initializes the current instance of the object. - """ - pass - - def write(self): - """Writes the contents of this object and returns the content as a dict object. - - Returns: - (dict). the object that represents the same data as the current instance. - """ - return _write_complex_object(self._defaults, self._values) - diff --git a/applicationinsights/channel/contracts/Utils.py b/applicationinsights/channel/contracts/Utils.py deleted file mode 100644 index 4c99d25d..00000000 --- a/applicationinsights/channel/contracts/Utils.py +++ /dev/null @@ -1,44 +0,0 @@ -import collections - -def _write_complex_object(defaults, values): - output = collections.OrderedDict() - for key in defaults.keys(): - default = defaults[key] - if key in values: - value = values[key] - if value == None: - value = default - elif default: - value = default - else: - continue - - if isinstance(value, list): - value_copy = [] - for item in value: - if hasattr(item, 'write') and callable(getattr(item, 'write')): - value_copy.append(item.write()) - else: - value_copy.append(item) - if len(value_copy) > 0: - output[key] = value_copy - elif isinstance(value, dict): - value_copy = collections.OrderedDict() - keys = sorted(value.keys()) - for item_key in keys: - item_value = value[item_key] - if hasattr(item_value, 'write') and callable(getattr(item_value, 'write')): - value_copy[item_key] = item_value.write() - else: - value_copy[item_key] = item_value - if len(value_copy) > 0: - output[key] = value_copy - elif hasattr(value, 'write') and callable(getattr(value, 'write')): - value_copy = value.write() - if len(value_copy) > 0: - output[key] = value_copy - else: - value_copy = value - output[key] = value_copy - - return output \ No newline at end of file diff --git a/applicationinsights/channel/contracts/__init__.py b/applicationinsights/channel/contracts/__init__.py deleted file mode 100644 index 3a144741..00000000 --- a/applicationinsights/channel/contracts/__init__.py +++ /dev/null @@ -1,26 +0,0 @@ -from .Domain import Domain -from .AvailabilityData import AvailabilityData -from .Base import Base -from .Application import Application -from .Device import Device -from .Location import Location -from .Operation import Operation -from .Session import Session -from .User import User -from .Cloud import Cloud -from .Internal import Internal -from .Data import Data -from .DataPointType import DataPointType -from .DataPoint import DataPoint -from .Envelope import Envelope -from .EventData import EventData -from .StackFrame import StackFrame -from .ExceptionDetails import ExceptionDetails -from .SeverityLevel import SeverityLevel -from .ExceptionData import ExceptionData -from .MessageData import MessageData -from .MetricData import MetricData -from .PageViewData import PageViewData -from .PageViewPerfData import PageViewPerfData -from .RemoteDependencyData import RemoteDependencyData -from .RequestData import RequestData diff --git a/applicationinsights/django/__init__.py b/applicationinsights/django/__init__.py deleted file mode 100644 index 3ce7cc45..00000000 --- a/applicationinsights/django/__init__.py +++ /dev/null @@ -1,10 +0,0 @@ -from .middleware import ApplicationInsightsMiddleware -from .logging import LoggingHandler -from . import common - -__all__ = ['ApplicationInsightsMiddleware', 'LoggingHandler', 'create_client'] - -def create_client(): - """Returns an :class:`applicationinsights.TelemetryClient` instance using the instrumentation key - and other settings found in the current Django project's `settings.py` file.""" - return common.create_client() diff --git a/applicationinsights/django/common.py b/applicationinsights/django/common.py deleted file mode 100644 index 335dd18f..00000000 --- a/applicationinsights/django/common.py +++ /dev/null @@ -1,82 +0,0 @@ -import collections - -from django.conf import settings -import applicationinsights - -ApplicationInsightsSettings = collections.namedtuple("ApplicationInsightsSettings", [ - "ikey", - "channel_settings", - "use_view_name", - "record_view_arguments", - "log_exceptions"]) - -ApplicationInsightsChannelSettings = collections.namedtuple("ApplicationInsightsChannelSettings", [ - "send_interval", - "send_time", - "endpoint"]) - -def load_settings(): - if hasattr(settings, "APPLICATION_INSIGHTS"): - config = settings.APPLICATION_INSIGHTS - elif hasattr(settings, "APPLICATIONINSIGHTS"): - config = settings.APPLICATIONINSIGHTS - else: - config = {} - - if not isinstance(config, dict): - config = {} - - return ApplicationInsightsSettings( - ikey=config.get("ikey"), - use_view_name=config.get("use_view_name", False), - record_view_arguments=config.get("record_view_arguments", False), - log_exceptions=config.get("log_exceptions", True), - channel_settings=ApplicationInsightsChannelSettings( - endpoint=config.get("endpoint"), - send_interval=config.get("send_interval"), - send_time=config.get("send_time"))) - -saved_clients = {} -saved_channels = {} - -def create_client(aisettings=None): - global saved_clients, saved_channels - - if aisettings is None: - aisettings = load_settings() - - if aisettings in saved_clients: - return saved_clients[aisettings] - - channel_settings = aisettings.channel_settings - - if channel_settings in saved_channels: - channel = saved_channels[channel_settings] - else: - sender = applicationinsights.channel.AsynchronousSender(service_endpoint_uri=channel_settings.endpoint) - - if channel_settings.send_time is not None: - sender.send_time = channel_settings.send_time - if channel_settings.send_interval is not None: - sender.send_interval = channel_settings.send_interval - - queue = applicationinsights.channel.AsynchronousQueue(sender) - channel = applicationinsights.channel.TelemetryChannel(None, queue) - saved_channels[channel_settings] = channel - - ikey = aisettings.ikey - if ikey is None: - return dummy_client("No ikey specified") - - client = applicationinsights.TelemetryClient(aisettings.ikey, channel) - saved_clients[aisettings] = client - return client - -def dummy_client(reason): - """Creates a dummy channel so even if we're not logging telemetry, we can still send - along the real object to things that depend on it to exist""" - - sender = applicationinsights.channel.NullSender() - queue = applicationinsights.channel.SynchronousQueue(sender) - channel = applicationinsights.channel.TelemetryChannel(None, queue) - return applicationinsights.TelemetryClient("00000000-0000-0000-0000-000000000000", channel) diff --git a/applicationinsights/django/logging.py b/applicationinsights/django/logging.py deleted file mode 100644 index 17baa004..00000000 --- a/applicationinsights/django/logging.py +++ /dev/null @@ -1,45 +0,0 @@ - -from . import common -from applicationinsights import logging - -import sys - -class LoggingHandler(logging.LoggingHandler): - """This class is a LoggingHandler that uses the same settings as the Django middleware to configure - the telemetry client. This can be referenced from LOGGING in your Django settings.py file. As an - example, this code would send all Django log messages--WARNING and up--to Application Insights: - - .. code:: python - - LOGGING = { - 'version': 1, - 'disable_existing_loggers': False, - 'handlers': { - # The application insights handler is here - 'appinsights': { - 'class': 'applicationinsights.django.LoggingHandler', - 'level': 'WARNING' - } - }, - 'loggers': { - 'django': { - 'handlers': ['appinsights'], - 'level': 'WARNING', - 'propagate': True, - } - } - } - - # You will need this anyway if you're using the middleware. - # See the middleware documentation for more information on configuring - # this setting: - APPLICATION_INSIGHTS = { - 'ikey': '00000000-0000-0000-0000-000000000000' - } - """ - def __init__(self, *args, **kwargs): - client = common.create_client() - new_kwargs = {} - new_kwargs.update(kwargs) - new_kwargs['telemetry_channel'] = client.channel - super(LoggingHandler, self).__init__(client.context.instrumentation_key, *args, **new_kwargs) diff --git a/applicationinsights/django/middleware.py b/applicationinsights/django/middleware.py deleted file mode 100644 index b4726b35..00000000 --- a/applicationinsights/django/middleware.py +++ /dev/null @@ -1,276 +0,0 @@ - -import datetime -import inspect -import sys -import time -import uuid - -from django.http import Http404 - -import applicationinsights -from applicationinsights.channel import contracts -from . import common - -try: - basestring # Python 2 -except NameError: # Python 3 - basestring = (str, ) - -# Pick a function to measure time; starting with 3.3, time.monotonic is available. -try: - TIME_FUNC = time.monotonic -except AttributeError: - TIME_FUNC = time.time - -class ApplicationInsightsMiddleware(object): - """This class is a Django middleware that automatically enables request and exception telemetry. Django versions - 1.7 and newer are supported. - - To enable, add this class to your settings.py file in MIDDLEWARE_CLASSES (pre-1.10) or MIDDLEWARE (1.10 and newer): - - .. code:: python - - # If on Django < 1.10 - MIDDLEWARE_CLASSES = [ - # ... or whatever is below for you ... - 'django.middleware.security.SecurityMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.middleware.common.CommonMiddleware', - 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', - 'django.middleware.clickjacking.XFrameOptionsMiddleware', - # ... or whatever is above for you ... - 'applicationinsights.django.ApplicationInsightsMiddleware', # Add this middleware to the end - ] - - # If on Django >= 1.10 - MIDDLEWARE = [ - # ... or whatever is below for you ... - 'django.middleware.security.SecurityMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.middleware.common.CommonMiddleware', - 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', - 'django.middleware.clickjacking.XFrameOptionsMiddleware', - # ... or whatever is above for you ... - 'applicationinsights.django.ApplicationInsightsMiddleware', # Add this middleware to the end - ] - - And then, add the following to your settings.py file: - - .. code:: python - - APPLICATION_INSIGHTS = { - # (required) Your Application Insights instrumentation key - 'ikey': "00000000-0000-0000-0000-000000000000", - - # (optional) By default, request names are logged as the request method - # and relative path of the URL. To log the fully-qualified view names - # instead, set this to True. Defaults to False. - 'use_view_name': True, - - # (optional) To log arguments passed into the views as custom properties, - # set this to True. Defaults to False. - 'record_view_arguments': True, - - # (optional) Exceptions are logged by default, to disable, set this to False. - 'log_exceptions': False, - - # (optional) Events are submitted to Application Insights asynchronously. - # send_interval specifies how often the queue is checked for items to submit. - # send_time specifies how long the sender waits for new input before recycling - # the background thread. - 'send_interval': 1.0, # Check every second - 'send_time': 3.0, # Wait up to 3 seconds for an event - - # (optional, uncommon) If you must send to an endpoint other than the - # default endpoint, specify it here: - 'endpoint': "https://dc.services.visualstudio.com/v2/track", - } - - Once these are in place, each request will have an `appinsights` object placed on it. - This object will have the following properties: - - * `client`: This is an instance of the :class:`applicationinsights.TelemetryClient` type, which will - submit telemetry to the same instrumentation key, and will parent each telemetry item to the current - request. - * `request`: This is the :class:`applicationinsights.channel.contracts.RequestData` instance for the - current request. You can modify properties on this object during the handling of the current request. - It will be submitted when the request has finished. - * `context`: This is the :class:`applicationinsights.channel.TelemetryContext` object for the current - ApplicationInsights sender. - - These properties will be present even when `DEBUG` is `True`, but it may not submit telemetry unless - `debug_ikey` is set in `APPLICATION_INSIGHTS`, above. - """ - def __init__(self, get_response=None): - self.get_response = get_response - - # Get configuration - self._settings = common.load_settings() - self._client = common.create_client(self._settings) - - # Pre-1.10 handler - def process_request(self, request): - # Populate context object onto request - addon = RequestAddon(self._client) - data = addon.request - context = addon.context - request.appinsights = addon - - # Basic request properties - data.start_time = datetime.datetime.utcnow().isoformat() + "Z" - data.http_method = request.method - data.url = request.build_absolute_uri() - data.name = "%s %s" % (request.method, request.path) - context.operation.name = data.name - context.operation.id = data.id - context.location.ip = request.META.get('REMOTE_ADDR', '') - context.user.user_agent = request.META.get('HTTP_USER_AGENT', '') - - # User - if hasattr(request, 'user'): - if request.user is not None and not request.user.is_anonymous and request.user.is_authenticated: - context.user.account_id = request.user.get_short_name() - - # Run and time the request - addon.start_stopwatch() - return None - - # Pre-1.10 handler - def process_response(self, request, response): - if hasattr(request, 'appinsights'): - addon = request.appinsights - duration = addon.measure_duration() - - data = addon.request - context = addon.context - - # Fill in data from the response - data.duration = addon.measure_duration() - data.response_code = response.status_code - data.success = response.status_code < 400 or response.status_code == 401 - - # Submit and return - self._client.channel.write(data, context) - - return response - - # 1.10 and up... - def __call__(self, request): - self.process_request(request) - response = self.get_response(request) - self.process_response(request, response) - return response - - def process_view(self, request, view_func, view_args, view_kwargs): - if not hasattr(request, "appinsights"): - return None - - data = request.appinsights.request - context = request.appinsights.context - - # Operation name is the method + url by default (set in __call__), - # If use_view_name is set, then we'll look up the name of the view. - if self._settings.use_view_name: - mod = inspect.getmodule(view_func) - if hasattr(view_func, "__name__"): - name = view_func.__name__ - elif hasattr(view_func, "__class__") and hasattr(view_func.__class__, "__name__"): - name = view_func.__class__.__name__ - else: - name = "" - - if mod: - opname = "%s %s.%s" % (data.http_method, mod.__name__, name) - else: - opname = "%s %s" % (data.http_method, name) - data.name = opname - context.operation.name = opname - - # Populate the properties with view arguments - if self._settings.record_view_arguments: - for i, arg in enumerate(view_args): - data.properties['view_arg_' + str(i)] = arg_to_str(arg) - - for k, v in view_kwargs.items(): - data.properties['view_arg_' + k] = arg_to_str(v) - - return None - - def process_exception(self, request, exception): - if not self._settings.log_exceptions: - return None - - if type(exception) is Http404: - return None - - _, _, tb = sys.exc_info() - if tb is None or exception is None: - # No actual traceback or exception info, don't bother logging. - return None - - client = applicationinsights.TelemetryClient(self._client.context.instrumentation_key, self._client.channel) - if hasattr(request, 'appinsights'): - client.context.operation.parent_id = request.appinsights.request.id - - client.track_exception(type(exception), exception, tb) - - return None - - def process_template_response(self, request, response): - if hasattr(request, 'appinsights') and hasattr(response, 'template_name'): - data = request.appinsights.request - data.properties['template_name'] = response.template_name - - return response - -class RequestAddon(object): - def __init__(self, client): - self._baseclient = client - self._client = None - self.request = contracts.RequestData() - self.request.id = str(uuid.uuid4()) - self.context = applicationinsights.channel.TelemetryContext() - self.context.instrumentation_key = client.context.instrumentation_key - self.context.operation.id = self.request.id - self._process_start_time = None - - @property - def client(self): - if self._client is None: - # Create a client that submits telemetry parented to the request. - self._client = applicationinsights.TelemetryClient(self.context.instrumentation_key, self._baseclient.channel) - self._client.context.operation.parent_id = self.context.operation.id - - return self._client - - def start_stopwatch(self): - self._process_start_time = TIME_FUNC() - - def measure_duration(self): - end_time = TIME_FUNC() - return ms_to_duration(int((end_time - self._process_start_time) * 1000)) - -def ms_to_duration(n): - duration_parts = [] - for multiplier in [1000, 60, 60, 24]: - duration_parts.append(n % multiplier) - n //= multiplier - - duration_parts.reverse() - duration = "%02d:%02d:%02d.%03d" % tuple(duration_parts) - if n: - duration = "%d.%s" % (n, duration) - - return duration - -def arg_to_str(arg): - if isinstance(arg, basestring): - return arg - if isinstance(arg, int): - return str(arg) - return repr(arg) diff --git a/applicationinsights/exceptions/__init__.py b/applicationinsights/exceptions/__init__.py deleted file mode 100644 index b30fceb4..00000000 --- a/applicationinsights/exceptions/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from .enable import enable \ No newline at end of file diff --git a/applicationinsights/exceptions/enable.py b/applicationinsights/exceptions/enable.py deleted file mode 100644 index 64888043..00000000 --- a/applicationinsights/exceptions/enable.py +++ /dev/null @@ -1,44 +0,0 @@ -import sys -from applicationinsights import TelemetryClient, channel - -original_excepthook = None -telemetry_channel = None -enabled_instrumentation_keys = [] - -def enable(instrumentation_key, *args, **kwargs): - """Enables the automatic collection of unhandled exceptions. Captured exceptions will be sent to the Application - Insights service before being re-thrown. Multiple calls to this function with different instrumentation keys result - in multiple instances being submitted, one for each key. - - .. code:: python - - from applicationinsights.exceptions import enable - - # set up exception capture - enable('') - - # raise an exception (this will be sent to the Application Insights service as an exception telemetry object) - raise Exception('Boom!') - - Args: - instrumentation_key (str). the instrumentation key to use while sending telemetry to the service. - """ - if not instrumentation_key: - raise Exception('Instrumentation key was required but not provided') - global original_excepthook - global telemetry_channel - telemetry_channel = kwargs.get('telemetry_channel') - if not original_excepthook: - original_excepthook = sys.excepthook - sys.excepthook = intercept_excepthook - if instrumentation_key not in enabled_instrumentation_keys: - enabled_instrumentation_keys.append(instrumentation_key) - - -def intercept_excepthook(type, value, traceback): - client = TelemetryClient('temp_key', telemetry_channel) - for instrumentation_key in enabled_instrumentation_keys: - client.context.instrumentation_key = instrumentation_key - client.track_exception(type, value, traceback) - client.flush() - original_excepthook(type, value, traceback) \ No newline at end of file diff --git a/applicationinsights/flask/__init__.py b/applicationinsights/flask/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/applicationinsights/flask/ext.py b/applicationinsights/flask/ext.py deleted file mode 100644 index 8b93848b..00000000 --- a/applicationinsights/flask/ext.py +++ /dev/null @@ -1,195 +0,0 @@ -from os import getenv - -try: - from werkzeug.exceptions import HTTPException -except ImportError: - HTTPException = None - -from applicationinsights import TelemetryClient -from applicationinsights.channel import AsynchronousSender -from applicationinsights.channel import AsynchronousQueue -from applicationinsights.channel import TelemetryChannel -from applicationinsights.logging import LoggingHandler -from applicationinsights.requests import WSGIApplication - -CONF_PREFIX = "APPINSIGHTS" - -CONF_KEY = CONF_PREFIX + "_INSTRUMENTATIONKEY" -CONF_ENDPOINT_URI = CONF_PREFIX + "_ENDPOINT_URI" -CONF_DISABLE_REQUEST_LOGGING = CONF_PREFIX + "_DISABLE_REQUEST_LOGGING" -CONF_DISABLE_TRACE_LOGGING = CONF_PREFIX + "_DISABLE_TRACE_LOGGING" -CONF_DISABLE_EXCEPTION_LOGGING = CONF_PREFIX + "_DISABLE_EXCEPTION_LOGGING" - - -class AppInsights(object): - """ This class represents a Flask extension that enables request telemetry, - trace logging and exception logging for a Flask application. The telemetry - will be sent to Application Insights service using the supplied - instrumentation key. - - The following Flask config variables can be used to configure the extension: - - - Set ``APPINSIGHTS_INSTRUMENTATIONKEY`` to a string to provide the - instrumentation key to send telemetry to application insights. - Alternatively, this value can also be provided via an environment variable - of the same name. - - - Set ``APPINSIGHTS_ENDPOINT_URI`` to a string to customize the telemetry - endpoint to which Application Insights will send the telemetry. - - - Set ``APPINSIGHTS_DISABLE_REQUEST_LOGGING`` to ``False`` to disable - logging of Flask requests to Application Insights. - - - Set ``APPINSIGHTS_DISABLE_TRACE_LOGGING`` to ``False`` to disable logging - of all log traces to Application Insights. - - - Set ``APPINSIGHTS_DISABLE_EXCEPTION_LOGGING`` to ``False`` to disable - logging of all exceptions to Application Insights. - - .. code:: python - - from flask import Flask - from applicationinsights.flask.ext import AppInsights - - # instantiate the Flask application - app = Flask(__name__) - app.config['APPINSIGHTS_INSTRUMENTATIONKEY'] = '' - - # log requests, traces and exceptions to the Application Insights service - appinsights = AppInsights(app) - - # define a simple route - @app.route('/') - def hello_world(): - return 'Hello World!' - - # run the application - if __name__ == '__main__': - app.run() - """ - def __init__(self, app=None): - """ - Initialize a new instance of the extension. - - Args: - app (flask.Flask). the Flask application for which to initialize the extension. - """ - self._key = None - self._endpoint_uri = None - self._channel = None - self._requests_middleware = None - self._trace_log_handler = None - self._exception_telemetry_client = None - - if app: - self.init_app(app) - - def init_app(self, app): - """ - Initializes the extension for the provided Flask application. - - Args: - app (flask.Flask). the Flask application for which to initialize the extension. - """ - self._key = app.config.get(CONF_KEY) or getenv(CONF_KEY) - - if not self._key: - return - - self._endpoint_uri = app.config.get(CONF_ENDPOINT_URI) - sender = AsynchronousSender(self._endpoint_uri) - - queue = AsynchronousQueue(sender) - self._channel = TelemetryChannel(None, queue) - - self._init_request_logging(app) - self._init_trace_logging(app) - self._init_exception_logging(app) - - @property - def context(self): - """ - Accesses the telemetry context. - - Returns: - (applicationinsights.channel.TelemetryContext). The Application Insights telemetry context. - """ - return self._channel.context - - def _init_request_logging(self, app): - """ - Sets up request logging unless ``APPINSIGHTS_DISABLE_REQUEST_LOGGING`` - is set in the Flask config. - - Args: - app (flask.Flask). the Flask application for which to initialize the extension. - """ - enabled = not app.config.get(CONF_DISABLE_REQUEST_LOGGING, False) - - if not enabled: - return - - self._requests_middleware = WSGIApplication( - self._key, app.wsgi_app, telemetry_channel=self._channel) - - app.wsgi_app = self._requests_middleware - - def _init_trace_logging(self, app): - """ - Sets up trace logging unless ``APPINSIGHTS_DISABLE_TRACE_LOGGING`` is - set in the Flask config. - - Args: - app (flask.Flask). the Flask application for which to initialize the extension. - """ - enabled = not app.config.get(CONF_DISABLE_TRACE_LOGGING, False) - - if not enabled: - return - - self._trace_log_handler = LoggingHandler( - self._key, telemetry_channel=self._channel) - - app.logger.addHandler(self._trace_log_handler) - - def _init_exception_logging(self, app): - """ - Sets up exception logging unless ``APPINSIGHTS_DISABLE_EXCEPTION_LOGGING`` - is set in the Flask config. - - Args: - app (flask.Flask). the Flask application for which to initialize the extension. - """ - enabled = not app.config.get(CONF_DISABLE_EXCEPTION_LOGGING, False) - - if not enabled: - return - - exception_telemetry_client = TelemetryClient( - self._key, telemetry_channel=self._channel) - - @app.errorhandler(Exception) - def exception_handler(exception): - if HTTPException and isinstance(exception, HTTPException): - return exception - - try: - raise exception - except Exception: - exception_telemetry_client.track_exception() - finally: - raise exception - - self._exception_telemetry_client = exception_telemetry_client - - def flush(self): - """Flushes the queued up telemetry to the service. - """ - if self._requests_middleware: - self._requests_middleware.flush() - - if self._trace_log_handler: - self._trace_log_handler.flush() - - if self._exception_telemetry_client: - self._exception_telemetry_client.flush() diff --git a/applicationinsights/logging/LoggingHandler.py b/applicationinsights/logging/LoggingHandler.py deleted file mode 100644 index d0550acb..00000000 --- a/applicationinsights/logging/LoggingHandler.py +++ /dev/null @@ -1,132 +0,0 @@ -import logging -import applicationinsights -from weakref import WeakValueDictionary -from applicationinsights.channel import AsynchronousSender, AsynchronousQueue -from applicationinsights.channel import SynchronousSender, SynchronousQueue -from applicationinsights.channel import TelemetryChannel - -enabled_instrumentation_keys = WeakValueDictionary() - -def enable(instrumentation_key, *args, **kwargs): - """Enables the Application Insights logging handler for the root logger for the supplied instrumentation key. - Multiple calls to this function with different instrumentation keys result in multiple handler instances. - - .. code:: python - - import logging - from applicationinsights.logging import enable - - # set up logging - enable('') - - # log something (this will be sent to the Application Insights service as a trace) - logging.info('This is a message') - - # logging shutdown will cause a flush of all un-sent telemetry items - # alternatively set up an async channel via enable('', async_=True) - - Args: - instrumentation_key (str). the instrumentation key to use while sending telemetry to the service. - - Keyword Args: - async_ (bool): Whether to use an async channel for the telemetry. Defaults to False. - endpoint (str): The custom endpoint to which to send the telemetry. Defaults to None. - level (Union[int, str]): The level to set for the logger. Defaults to INFO. - - Returns: - :class:`ApplicationInsightsHandler`. the newly created or existing handler. - """ - if not instrumentation_key: - raise Exception('Instrumentation key was required but not provided') - if instrumentation_key in enabled_instrumentation_keys: - logging.getLogger().removeHandler(enabled_instrumentation_keys[instrumentation_key]) - async_ = kwargs.pop('async_', False) - endpoint = kwargs.pop('endpoint', None) - telemetry_channel = kwargs.get('telemetry_channel') - if telemetry_channel and async_: - raise Exception('Incompatible arguments async_ and telemetry_channel') - if telemetry_channel and endpoint: - raise Exception('Incompatible arguments endpoint and telemetry_channel') - if not telemetry_channel: - if async_: - sender, queue = AsynchronousSender, AsynchronousQueue - else: - sender, queue = SynchronousSender, SynchronousQueue - kwargs['telemetry_channel'] = TelemetryChannel(queue=queue(sender(endpoint))) - log_level = kwargs.pop('level', logging.INFO) - handler = LoggingHandler(instrumentation_key, *args, **kwargs) - handler.setLevel(log_level) - enabled_instrumentation_keys[instrumentation_key] = handler - logging.getLogger().addHandler(handler) - return handler - - -class LoggingHandler(logging.Handler): - """This class represents an integration point between Python's logging framework and the Application Insights - service. - - Logging records are sent to the service either as simple Trace telemetry or as Exception telemetry (in the case - of exception information being available). - - .. code:: python - - import logging - from applicationinsights.logging import ApplicationInsightsHandler - - # set up logging - handler = ApplicationInsightsHandler('') - logging.basicConfig(handlers=[ handler ], format='%(levelname)s: %(message)s', level=logging.DEBUG) - - # log something (this will be sent to the Application Insights service as a trace) - logging.info('This is a message') - - # logging shutdown will cause a flush of all un-sent telemetry items - # alternatively flush manually via handler.flush() - """ - def __init__(self, instrumentation_key, *args, **kwargs): - """ - Initialize a new instance of the class. - - Args: - instrumentation_key (str). the instrumentation key to use while sending telemetry to the service. - """ - if not instrumentation_key: - raise Exception('Instrumentation key was required but not provided') - telemetry_channel = kwargs.get('telemetry_channel') - if 'telemetry_channel' in kwargs: - del kwargs['telemetry_channel'] - self.client = applicationinsights.TelemetryClient(instrumentation_key, telemetry_channel) - super(LoggingHandler, self).__init__(*args, **kwargs) - - def flush(self): - """Flushes the queued up telemetry to the service. - """ - self.client.flush() - return super(LoggingHandler, self).flush() - - def emit(self, record): - """Emit a record. - - If a formatter is specified, it is used to format the record. If exception information is present, an Exception - telemetry object is sent instead of a Trace telemetry object. - - Args: - record (:class:`logging.LogRecord`). the record to format and send. - """ - # the set of properties that will ride with the record - properties = { - 'process': record.processName, - 'module': record.module, - 'fileName': record.filename, - 'lineNumber': record.lineno, - 'level': record.levelname, - } - - # if we have exec_info, we will use it as an exception - if record.exc_info: - self.client.track_exception(*record.exc_info, properties=properties) - return - - # if we don't simply format the message and send the trace - formatted_message = self.format(record) - self.client.track_trace(formatted_message, properties=properties, severity=record.levelname) diff --git a/applicationinsights/logging/__init__.py b/applicationinsights/logging/__init__.py deleted file mode 100644 index 003329a2..00000000 --- a/applicationinsights/logging/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -from .LoggingHandler import enable -from .LoggingHandler import LoggingHandler \ No newline at end of file diff --git a/applicationinsights/requests/WSGIApplication.py b/applicationinsights/requests/WSGIApplication.py deleted file mode 100644 index 48bd7b94..00000000 --- a/applicationinsights/requests/WSGIApplication.py +++ /dev/null @@ -1,108 +0,0 @@ -import datetime -import re -import uuid -import applicationinsights - -class WSGIApplication(object): - """ This class represents a WSGI wrapper that enables request telemetry for existing WSGI applications. The request - telemetry will be sent to Application Insights service using the supplied instrumentation key. - - .. code:: python - - from applicationinsights.requests import WSGIApplication - from paste.httpserver import serve - from pyramid.response import Response - from pyramid.view import view_config - - @view_config() - def hello(request): - return Response('Hello') - - if __name__ == '__main__': - from pyramid.config import Configurator - config = Configurator() - config.scan() - app = config.make_wsgi_app() - - # Enable Application Insights middleware - app = WSGIApplication('', app, common_properties={'service': 'hello_world_service'}) - - serve(app, host='0.0.0.0') - """ - def __init__(self, instrumentation_key, wsgi_application, *args, **kwargs): - """ - Initialize a new instance of the class. - - Args: - instrumentation_key (str). the instrumentation key to use while sending telemetry to the service.\n - wsgi_application (func). the WSGI application that we're wrapping. - """ - if not instrumentation_key: - raise Exception('Instrumentation key was required but not provided') - if not wsgi_application: - raise Exception('WSGI application was required but not provided') - telemetry_channel = kwargs.pop('telemetry_channel', None) - if not telemetry_channel: - sender = applicationinsights.channel.AsynchronousSender() - queue = applicationinsights.channel.AsynchronousQueue(sender) - telemetry_channel = applicationinsights.channel.TelemetryChannel(None, queue) - self.client = applicationinsights.TelemetryClient(instrumentation_key, telemetry_channel) - self.client.context.device.type = "PC" - self._wsgi_application = wsgi_application - self._common_properties = kwargs.pop('common_properties', {}) - - def flush(self): - """Flushes the queued up telemetry to the service. - """ - self.client.flush() - - def __call__(self, environ, start_response): - """Callable implementation for WSGI middleware. - - Args: - environ (dict). a dictionary containing all WSGI environment properties for this request.\n - start_response (func). a function used to store the status, HTTP headers to be sent to the client and optional exception information. - - Returns: - (obj). the response to send back to the client. - """ - start_time = datetime.datetime.utcnow() - name = environ.get('PATH_INFO') or '/' - closure = {'status': '200 OK'} - http_method = environ.get('REQUEST_METHOD', 'GET') - - self.client.context.operation.id = str(uuid.uuid4()) - # operation.parent_id ought to be the request id (not the operation id, but we don't have it yet) - self.client.context.operation.name = http_method + ' ' + name - - def status_interceptor(status_string, headers_array, exc_info=None): - closure['status'] = status_string - start_response(status_string, headers_array, exc_info) - - for part in self._wsgi_application(environ, status_interceptor): - yield part - - success = True - response_match = re.match(r'\s*(?P\d+)', closure['status']) - if response_match: - response_code = response_match.group('code') - if int(response_code) >= 400: - success = False - else: - response_code = closure['status'] - success = False - - url = name - query_string = environ.get('QUERY_STRING') - if query_string: - url += '?' + query_string - - scheme = environ.get('wsgi.url_scheme', 'http') - host = environ.get('HTTP_HOST', environ.get('SERVER_NAME', 'unknown')) - - url = scheme + '://' + host + url - - end_time = datetime.datetime.utcnow() - duration = int((end_time - start_time).total_seconds() * 1000) - - self.client.track_request(name, url, success, start_time.isoformat() + 'Z', duration, response_code, http_method, self._common_properties) diff --git a/applicationinsights/requests/__init__.py b/applicationinsights/requests/__init__.py deleted file mode 100644 index e4b11d5d..00000000 --- a/applicationinsights/requests/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from .WSGIApplication import WSGIApplication diff --git a/django_tests/all_tests.sh b/django_tests/all_tests.sh deleted file mode 100755 index 25e83290..00000000 --- a/django_tests/all_tests.sh +++ /dev/null @@ -1,69 +0,0 @@ -#!/bin/bash - -if [ -z $PYTHON ]; then - PYTHON=$(which python) -fi - -cd $(dirname $0) -BASEDIR=$(pwd) - -# Django/python compatibility matrix... -if $PYTHON -c "import sys; sys.exit(0 if sys.version_info < (3, 0) else 1)"; then - # Django2.0 won't support Python2 - DJANGO_VERSIONS='1.7.11 1.8.19 1.9.13 1.10.8 1.11.13' -elif $PYTHON -c "import sys; sys.exit(0 if sys.version_info < (3, 5) else 1)"; then - DJANGO_VERSIONS='1.7.11 1.8.19 1.9.13 1.10.8 1.11.13 2.0.6' -else - # python3.5 dropped html.parser.HtmlParserError versions older than Django1.8 won't work - DJANGO_VERSIONS='1.8.19 1.9.13 1.10.8 1.11.13 2.0.6' -fi - -# For each Django version... -for v in $DJANGO_VERSIONS -do - echo "" - echo "***" - echo "*** Running tests for Django $v" - echo "***" - echo "" - - # Create new directory - TMPDIR=$(mktemp -d) - function cleanup - { - rm -rf $TMPDIR - exit $1 - } - - trap cleanup EXIT SIGINT - - # Create virtual environment - if $PYTHON -c "import sys; sys.exit(0 if sys.version_info < (3, 3) else 1)"; then - if command -v virtualenv >/dev/null 2>&1; then - virtualenv -p $PYTHON $TMPDIR/env || exit $? - elif $PYTHON -c "import sys; sys.exit(0 if sys.version_info < (3, 0) else 1)"; then - if command -v virtualenv2 >/dev/null 2>&1; then - virtualenv2 -p $PYTHON $TMPDIR/env || exit $? - fi - else - echo Requires virtualenv - exit 1 - fi - else - $PYTHON -m venv $TMPDIR/env - fi - - # Install Django version + application insights - . $TMPDIR/env/bin/activate - pip install Django==$v || exit $? - cd $BASEDIR/.. - python setup.py install || exit $? - - # Run tests - cd $BASEDIR - bash ./run_test.sh || exit $? - - # Remove venv - deactivate - rm -rf $TMPDIR -done diff --git a/django_tests/run_test.sh b/django_tests/run_test.sh deleted file mode 100755 index f10879c2..00000000 --- a/django_tests/run_test.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/bash - -# It is expected at this point that django and applicationinsights are both installed into a -# virtualenv. -django_version=$(python -c "import django ; print('.'.join(map(str, django.VERSION[0:2])))") -test $? -eq 0 || exit 1 - -# Create a new temporary work directory -TMPDIR=$(mktemp -d) -SRCDIR=$(pwd) -function cleanup -{ - cd $SRCDIR - rm -rf $TMPDIR - exit $1 -} -trap cleanup EXIT SIGINT -cd $TMPDIR - -# Set up Django project -django-admin startproject aitest -cd aitest -cp $SRCDIR/views.py aitest/views.py -cp $SRCDIR/tests.py aitest/tests.py -cp $SRCDIR/urls.py aitest/urls.py -cp $SRCDIR/template.html aitest/template.html - -./manage.py test -exit $? diff --git a/django_tests/template.html b/django_tests/template.html deleted file mode 100644 index c02dd841..00000000 --- a/django_tests/template.html +++ /dev/null @@ -1 +0,0 @@ -Test django template: {{ context }} diff --git a/django_tests/tests.py b/django_tests/tests.py deleted file mode 100644 index c246ca9b..00000000 --- a/django_tests/tests.py +++ /dev/null @@ -1,366 +0,0 @@ -import os -import logging - -import django -from django.test import TestCase, Client, modify_settings, override_settings - -from applicationinsights import TelemetryClient -from applicationinsights.channel import TelemetryChannel, SynchronousQueue, SenderBase, NullSender, AsynchronousSender -from applicationinsights.channel.SenderBase import DEFAULT_ENDPOINT_URL as DEFAULT_ENDPOINT -from applicationinsights.django import common - -if django.VERSION > (1, 10): - MIDDLEWARE_NAME = "MIDDLEWARE" -else: - MIDDLEWARE_NAME = "MIDDLEWARE_CLASSES" - -TEST_IKEY = '12345678-1234-5678-9012-123456789abc' -TEST_ENDPOINT = 'https://test.endpoint/v2/track' -PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__)) - -class AITestCase(TestCase): - def plug_sender(self): - # Reset saved objects - common.saved_clients = {} - common.saved_channels = {} - - # Create a client and mock out the sender - client = common.create_client() - sender = MockSender() - client._channel = TelemetryChannel(None, SynchronousQueue(sender)) - self.events = sender.events - self.channel = client.channel - - def get_events(self, count): - self.channel.flush() - self.assertEqual(len(self.events), count, "Expected %d event(s) in queue (%d actual)" % (count, len(self.events))) - if count == 1: - return self.events[0] - return self.events - -@modify_settings(**{MIDDLEWARE_NAME: {'append': 'applicationinsights.django.ApplicationInsightsMiddleware'}}) -@override_settings( - APPLICATION_INSIGHTS={'ikey': TEST_IKEY}, - # Templates for 1.7 - TEMPLATE_DIRS=(PROJECT_ROOT,), - TEMPLATE_LOADERS=('django.template.loaders.filesystem.Loader',), - # Templates for 1.8 and up - TEMPLATES=[{'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [PROJECT_ROOT]}]) -class MiddlewareTests(AITestCase): - def setUp(self): - self.plug_sender() - - def test_basic_request(self): - """Tests that hitting a simple view generates a telemetry item with the correct properties""" - response = self.client.get('/') - self.assertEqual(response.status_code, 200) - - event = self.get_events(1) - tags = event['tags'] - data = event['data']['baseData'] - self.assertEqual(event['name'], 'Microsoft.ApplicationInsights.Request', "Event type") - self.assertEqual(event['iKey'], TEST_IKEY) - self.assertEqual(tags['ai.operation.name'], 'GET /', "Operation name") - self.assertEqual(data['name'], 'GET /', "Request name") - self.assertEqual(data['responseCode'], 200, "Status code") - self.assertEqual(data['success'], True, "Success value") - self.assertEqual(data['url'], 'http://testserver/', "Request url") - - def test_logger(self): - """Tests that traces logged from inside of a view are submitted and parented to the request telemetry item""" - response = self.client.get('/logger') - self.assertEqual(response.status_code, 200) - - logev, reqev = self.get_events(2) - - # Check request event (minimal, since we validate this elsewhere) - tags = reqev['tags'] - data = reqev['data']['baseData'] - reqid = tags['ai.operation.id'] - self.assertEqual(reqev['name'], 'Microsoft.ApplicationInsights.Request', "Event type") - self.assertEqual(data['id'], reqid, "Request id") - self.assertEqual(data['name'], 'GET /logger', "Operation name") - self.assertEqual(data['url'], 'http://testserver/logger', "Request url") - - self.assertTrue(reqid, "Request id not empty") - - # Check log event - tags = logev['tags'] - data = logev['data']['baseData'] - self.assertEqual(logev['name'], 'Microsoft.ApplicationInsights.Message', "Event type") - self.assertEqual(logev['iKey'], TEST_IKEY) - self.assertEqual(tags['ai.operation.parentId'], reqid, "Parent id") - self.assertEqual(data['message'], 'Logger message', "Log message") - self.assertEqual(data['properties']['property'], 'value', "Property=value") - - def test_thrower(self): - """Tests that unhandled exceptions generate an exception telemetry item parented to the request telemetry item""" - with self.assertRaises(ValueError): - self.client.get('/thrower') - - errev, reqev = self.get_events(2) - - # Check request event - tags = reqev['tags'] - data = reqev['data']['baseData'] - reqid = tags['ai.operation.id'] - self.assertEqual(reqev['name'], 'Microsoft.ApplicationInsights.Request', "Event type") - self.assertEqual(reqev['iKey'], TEST_IKEY) - self.assertEqual(data['id'], reqid, "Request id") - self.assertEqual(data['responseCode'], 500, "Response code") - self.assertEqual(data['success'], False, "Success value") - self.assertEqual(data['name'], 'GET /thrower', "Request name") - self.assertEqual(data['url'], 'http://testserver/thrower', "Request url") - - self.assertTrue(reqid, "Request id not empty") - - # Check exception event - tags = errev['tags'] - data = errev['data']['baseData'] - self.assertEqual(errev['name'], 'Microsoft.ApplicationInsights.Exception', "Event type") - self.assertEqual(tags['ai.operation.parentId'], reqid, "Exception parent id") - self.assertEqual(len(data['exceptions']), 1, "Exception count") - exc = data['exceptions'][0] - self.assertEqual(exc['typeName'], 'ValueError', "Exception type") - self.assertEqual(exc['hasFullStack'], True, "Has full stack") - self.assertEqual(exc['parsedStack'][0]['method'], 'thrower', "Stack frame method name") - - def test_error(self): - """Tests that Http404 exception does not generate an exception event - and the request telemetry item properly logs the failure""" - response = self.client.get("/errorer") - self.assertEqual(response.status_code, 404) - - event = self.get_events(1) - tags = event['tags'] - data = event['data']['baseData'] - self.assertEqual(event['name'], 'Microsoft.ApplicationInsights.Request', "Event type") - self.assertEqual(tags['ai.operation.name'], 'GET /errorer', "Operation name") - self.assertEqual(data['responseCode'], 404, "Status code") - self.assertEqual(data['success'], False, "Success value") - self.assertEqual(data['url'], 'http://testserver/errorer', "Request url") - - def test_template(self): - """Tests that views using templates operate correctly and that template data is logged""" - response = self.client.get("/templater/ctx") - self.assertEqual(response.status_code, 200) - - event = self.get_events(1) - data = event['data']['baseData'] - self.assertEqual(event['name'], 'Microsoft.ApplicationInsights.Request', "Event type") - self.assertEqual(data['success'], True, "Success value") - self.assertEqual(data['responseCode'], 200, "Status code") - self.assertEqual(data['properties']['template_name'], 'template.html', "Template name") - - def test_no_view_arguments(self): - """Tests that view id logging is off by default""" - self.plug_sender() - response = self.client.get('/getid/24') - self.assertEqual(response.status_code, 200) - - event = self.get_events(1) - data = event['data']['baseData'] - self.assertEqual(event['name'], 'Microsoft.ApplicationInsights.Request', "Event type") - self.assertTrue('properties' not in data or 'view_arg_0' not in data['properties']) - - def test_no_view(self): - """Tests that requests to URLs not backed by views are still logged""" - response = self.client.get('/this/view/does/not/exist') - self.assertEqual(response.status_code, 404) - - event = self.get_events(1) - tags = event['tags'] - data = event['data']['baseData'] - self.assertEqual(event['name'], 'Microsoft.ApplicationInsights.Request', "Event type") - self.assertEqual(data['responseCode'], 404, "Status code") - self.assertEqual(data['success'], False, "Success value") - self.assertEqual(data['name'], 'GET /this/view/does/not/exist', "Request name") - self.assertEqual(data['url'], 'http://testserver/this/view/does/not/exist', "Request url") - - def test_401_success(self): - """Tests that a 401 status code is considered successful""" - response = self.client.get("/returncode/401") - self.assertEqual(response.status_code, 401) - - event = self.get_events(1) - tags = event['tags'] - data = event['data']['baseData'] - self.assertEqual(event['name'], 'Microsoft.ApplicationInsights.Request', "Event type") - self.assertEqual(tags['ai.operation.name'], 'GET /returncode/401', "Operation name") - self.assertEqual(data['responseCode'], 401, "Status code") - self.assertEqual(data['success'], True, "Success value") - self.assertEqual(data['url'], 'http://testserver/returncode/401', "Request url") - -@modify_settings(**{MIDDLEWARE_NAME: {'append': 'applicationinsights.django.ApplicationInsightsMiddleware'}}) -class RequestSettingsTests(AITestCase): - # This type needs to plug the sender during the test -- doing it in setUp would have nil effect - # because each method's override_settings wouldn't have happened by then. - - @override_settings(APPLICATION_INSIGHTS={'ikey': TEST_IKEY, 'use_view_name': True}) - def test_use_view_name(self): - """Tests that request names are set to view names when use_view_name=True""" - self.plug_sender() - self.client.get('/') - event = self.get_events(1) - self.assertEqual(event['data']['baseData']['name'], 'GET aitest.views.home', "Request name") - self.assertEqual(event['tags']['ai.operation.name'], 'GET aitest.views.home', "Operation name") - - @override_settings(APPLICATION_INSIGHTS={'ikey': TEST_IKEY, 'use_view_name': False}) - def test_use_view_name_off(self): - """Tests that request names are set to URLs when use_view_name=False""" - self.plug_sender() - self.client.get('/') - event = self.get_events(1) - self.assertEqual(event['data']['baseData']['name'], 'GET /', "Request name") - self.assertEqual(event['tags']['ai.operation.name'], 'GET /', "Operation name") - - @override_settings(APPLICATION_INSIGHTS={'ikey': TEST_IKEY, 'use_view_name': True}) - def test_view_name_class(self): - """Tests that classes can be correctly identified when use_view_name=True""" - self.plug_sender() - self.client.get('/class') - event = self.get_events(1) - self.assertEqual(event['data']['baseData']['name'], 'GET aitest.views.classview', "Request name") - self.assertEqual(event['tags']['ai.operation.name'], 'GET aitest.views.classview', "Operation name") - - @override_settings(APPLICATION_INSIGHTS=None) - def test_appinsights_still_supplied(self): - """Tests that appinsights is still added to requests even if APPLICATION_INSIGHTS is unspecified""" - # This uses request.appinsights -- it will crash if it's not there. - response = self.client.get('/logger') - self.assertEqual(response.status_code, 200) - - @override_settings(APPLICATION_INSIGHTS={'ikey': TEST_IKEY, 'record_view_arguments': True}) - def test_view_id(self): - """Tests that view arguments are logged when record_view_arguments=True""" - self.plug_sender() - response = self.client.get('/getid/24') - self.assertEqual(response.status_code, 200) - - event = self.get_events(1) - props = event['data']['baseData']['properties'] - self.assertEqual(event['name'], 'Microsoft.ApplicationInsights.Request', "Event type") - self.assertEqual(props['view_arg_0'], '24', "View argument") - - @override_settings(APPLICATION_INSIGHTS={'ikey': TEST_IKEY, 'log_exceptions': False}) - def test_log_exceptions_off(self): - """Tests that exceptions are not logged when log_exceptions=False""" - self.plug_sender() - with self.assertRaises(ValueError): - response = self.client.get('/thrower') - - event = self.get_events(1) - data = event['data']['baseData'] - self.assertEqual(event['name'], 'Microsoft.ApplicationInsights.Request', "Event type") - self.assertEqual(data['responseCode'], 500, "Response code") - -class SettingsTests(TestCase): - def setUp(self): - # Just clear out any cached objects - common.saved_clients = {} - common.saved_channels = {} - - def test_no_app_insights(self): - """Tests that events are swallowed when APPLICATION_INSIGHTS is unspecified""" - client = common.create_client() - self.assertTrue(type(client.channel.sender) is NullSender) - - @override_settings(APPLICATION_INSIGHTS={'ikey': TEST_IKEY}) - def test_default_endpoint(self): - """Tests that the default endpoint is used when endpoint is unspecified""" - client = common.create_client() - self.assertEqual(client.channel.sender.service_endpoint_uri, DEFAULT_ENDPOINT) - - @override_settings(APPLICATION_INSIGHTS={'ikey': TEST_IKEY, 'endpoint': TEST_ENDPOINT}) - def test_overridden_endpoint(self): - """Tests that the endpoint is used when specified""" - client = common.create_client() - self.assertEqual(client.channel.sender.service_endpoint_uri, TEST_ENDPOINT) - - @override_settings(APPLICATION_INSIGHTS={'ikey': TEST_IKEY, 'send_time': 999}) - def test_send_time(self): - """Tests that send_time is propagated to sender""" - client = common.create_client() - self.assertEqual(client.channel.sender.send_time, 999) - - @override_settings(APPLICATION_INSIGHTS={'ikey': TEST_IKEY, 'send_interval': 999}) - def test_send_interval(self): - """Tests that send_interval is propagated to sender""" - client = common.create_client() - self.assertEqual(client.channel.sender.send_interval, 999) - - @override_settings(APPLICATION_INSIGHTS={'ikey': TEST_IKEY}) - def test_default_send_time(self): - """Tests that send_time is equal to the default when it is unspecified""" - client = common.create_client() - self.assertEqual(client.channel.sender.send_time, AsynchronousSender().send_time) - - @override_settings(APPLICATION_INSIGHTS={'ikey': TEST_IKEY}) - def test_default_send_interval(self): - """Tests that send_interval is equal to the default when it is unspecified""" - client = common.create_client() - self.assertEqual(client.channel.sender.send_interval, AsynchronousSender().send_interval) - - -@override_settings(LOGGING={ - 'version': 1, - 'handlers': { - 'appinsights': { - 'class': 'applicationinsights.django.LoggingHandler', - 'level': 'INFO', - } - }, - 'loggers': { - __name__: { - 'handlers': ['appinsights'], - 'level': 'INFO', - } - } -}, APPLICATION_INSIGHTS={'ikey': TEST_IKEY}) -class LoggerTests(AITestCase): - def setUp(self): - self.plug_sender() - - def test_log_error(self): - """Tests an error trace telemetry is properly sent""" - django.setup() - logger = logging.getLogger(__name__) - msg = "An error log message" - logger.error(msg) - - event = self.get_events(1) - data = event['data']['baseData'] - props = data['properties'] - self.assertEqual(event['name'], 'Microsoft.ApplicationInsights.Message', "Event type") - self.assertEqual(event['iKey'], TEST_IKEY) - self.assertEqual(data['message'], msg, "Log message") - self.assertEqual(data['severityLevel'], 3, "Severity level") - self.assertEqual(props['fileName'], 'tests.py', "Filename property") - self.assertEqual(props['level'], 'ERROR', "Level property") - self.assertEqual(props['module'], 'tests', "Module property") - - def test_log_info(self): - """Tests an info trace telemetry is properly sent""" - django.setup() - logger = logging.getLogger(__name__) - msg = "An info message" - logger.info(msg) - - event = self.get_events(1) - data = event['data']['baseData'] - props = data['properties'] - self.assertEqual(event['name'], 'Microsoft.ApplicationInsights.Message', "Event type") - self.assertEqual(event['iKey'], TEST_IKEY) - self.assertEqual(data['message'], msg, "Log message") - self.assertEqual(data['severityLevel'], 1, "Severity level") - self.assertEqual(props['fileName'], 'tests.py', "Filename property") - self.assertEqual(props['level'], 'INFO', "Level property") - self.assertEqual(props['module'], 'tests', "Module property") - -class MockSender(SenderBase): - def __init__(self): - SenderBase.__init__(self, DEFAULT_ENDPOINT) - self.events = [] - - def send(self, data): - self.events.extend(a.write() for a in data) diff --git a/django_tests/urls.py b/django_tests/urls.py deleted file mode 100644 index 996bc31e..00000000 --- a/django_tests/urls.py +++ /dev/null @@ -1,15 +0,0 @@ -from django.conf.urls import include, url -from django.contrib import admin - -from . import views - -urlpatterns = [ - url(r'^$', views.home, name='home'), - url(r'^logger$', views.logger, name='logger'), - url(r'^thrower$', views.thrower, name='thrower'), - url(r'^errorer$', views.errorer, name='errorer'), - url(r'^getid/([0-9]+)$', views.getid, name='getid'), - url(r'^returncode/([0-9]+)$', views.returncode, name='returncode'), - url(r'^templater/([^/]*)$', views.templater, name='templater'), - url(r'^class$', views.classview(), name='class'), -] diff --git a/django_tests/views.py b/django_tests/views.py deleted file mode 100644 index 44c56ad5..00000000 --- a/django_tests/views.py +++ /dev/null @@ -1,31 +0,0 @@ -from django.http import HttpResponse, Http404 -from django.template.response import TemplateResponse - -def home(request): - return HttpResponse("Welcome home") - -def logger(request): - request.appinsights.client.track_trace("Logger message", {"property": "value"}) - return HttpResponse("We logged a message") - -def thrower(request): - raise ValueError("This is an unexpected exception") - -def errorer(request): - raise Http404("This is a 404 error") - -def echoer(request): - return HttpResponse(request.appinsights.request.id) - -def getid(request, id): - return HttpResponse(str(id)) - -def returncode(request, id): - return HttpResponse("Status code set to %s" % id, status=int(id)) - -def templater(request, data): - return TemplateResponse(request, 'template.html', {'context': data}) - -class classview: - def __call__(self, request): - return HttpResponse("You called a class.") diff --git a/doc/Makefile b/doc/Makefile deleted file mode 100644 index 96b67145..00000000 --- a/doc/Makefile +++ /dev/null @@ -1,183 +0,0 @@ -# Makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -PAPER = -BUILDDIR = build - -# User-friendly check for sphinx-build -ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) -$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) -endif - -# Internal variables. -PAPEROPT_a4 = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . -# the i18n builder cannot share the environment and doctrees with the others -I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . - -.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest coverage gettext - -help: - @echo "Please use \`make ' where is one of" - @echo " html to make standalone HTML files" - @echo " dirhtml to make HTML files named index.html in directories" - @echo " singlehtml to make a single large HTML file" - @echo " pickle to make pickle files" - @echo " json to make JSON files" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " qthelp to make HTML files and a qthelp project" - @echo " devhelp to make HTML files and a Devhelp project" - @echo " epub to make an epub" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " latexpdf to make LaTeX files and run them through pdflatex" - @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" - @echo " text to make text files" - @echo " man to make manual pages" - @echo " texinfo to make Texinfo files" - @echo " info to make Texinfo files and run them through makeinfo" - @echo " gettext to make PO message catalogs" - @echo " changes to make an overview of all changed/added/deprecated items" - @echo " xml to make Docutils-native XML files" - @echo " pseudoxml to make pseudoxml-XML files for display purposes" - @echo " linkcheck to check all external links for integrity" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" - @echo " coverage to run coverage check of the documentation (if enabled)" - -clean: - rm -rf $(BUILDDIR)/* - -html: - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." - -dirhtml: - $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." - -singlehtml: - $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml - @echo - @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." - -pickle: - $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle - @echo - @echo "Build finished; now you can process the pickle files." - -json: - $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json - @echo - @echo "Build finished; now you can process the JSON files." - -htmlhelp: - $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp - @echo - @echo "Build finished; now you can run HTML Help Workshop with the" \ - ".hhp project file in $(BUILDDIR)/htmlhelp." - -qthelp: - $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp - @echo - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ - ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/ApplicationInsightsSDKforPython.qhcp" - @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/ApplicationInsightsSDKforPython.qhc" - -devhelp: - $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp - @echo - @echo "Build finished." - @echo "To view the help file:" - @echo "# mkdir -p $$HOME/.local/share/devhelp/ApplicationInsightsSDKforPython" - @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/ApplicationInsightsSDKforPython" - @echo "# devhelp" - -epub: - $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub - @echo - @echo "Build finished. The epub file is in $(BUILDDIR)/epub." - -latex: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo - @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." - @echo "Run \`make' in that directory to run these through (pdf)latex" \ - "(use \`make latexpdf' here to do that automatically)." - -latexpdf: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through pdflatex..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -latexpdfja: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through platex and dvipdfmx..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -text: - $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text - @echo - @echo "Build finished. The text files are in $(BUILDDIR)/text." - -man: - $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man - @echo - @echo "Build finished. The manual pages are in $(BUILDDIR)/man." - -texinfo: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo - @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." - @echo "Run \`make' in that directory to run these through makeinfo" \ - "(use \`make info' here to do that automatically)." - -info: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo "Running Texinfo files through makeinfo..." - make -C $(BUILDDIR)/texinfo info - @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." - -gettext: - $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale - @echo - @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." - -changes: - $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes - @echo - @echo "The overview file is in $(BUILDDIR)/changes." - -linkcheck: - $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck - @echo - @echo "Link check complete; look for any errors in the above output " \ - "or in $(BUILDDIR)/linkcheck/output.txt." - -doctest: - $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest - @echo "Testing of doctests in the sources finished, look at the " \ - "results in $(BUILDDIR)/doctest/output.txt." - -coverage: - $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage - @echo "Testing of coverage in the sources finished, look at the " \ - "results in $(BUILDDIR)/coverage/python.txt." - -xml: - $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml - @echo - @echo "Build finished. The XML files are in $(BUILDDIR)/xml." - -pseudoxml: - $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml - @echo - @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." diff --git a/doc/applicationinsights.channel.contracts.rst b/doc/applicationinsights.channel.contracts.rst deleted file mode 100644 index abcfdec0..00000000 --- a/doc/applicationinsights.channel.contracts.rst +++ /dev/null @@ -1,152 +0,0 @@ -.. toctree:: - :hidden: - -applicationinsights.channel.contracts module -============================================ - -Application class ------------------ -.. autoclass:: applicationinsights.channel.contracts.Application - :members: - :member-order: groupwise - :inherited-members: - -Data class ----------- -.. autoclass:: applicationinsights.channel.contracts.Data - :members: - :member-order: groupwise - :inherited-members: - -DataPoint class ---------------- -.. autoclass:: applicationinsights.channel.contracts.DataPoint - :members: - :member-order: groupwise - :inherited-members: - -DataPointType class -------------------- -.. autoclass:: applicationinsights.channel.contracts.DataPointType - :members: - :member-order: groupwise - :inherited-members: - -Device class ------------- -.. autoclass:: applicationinsights.channel.contracts.Device - :members: - :member-order: groupwise - :inherited-members: - -Envelope class --------------- -.. autoclass:: applicationinsights.channel.contracts.Envelope - :members: - :member-order: groupwise - :inherited-members: - -EventData class ---------------- -.. autoclass:: applicationinsights.channel.contracts.EventData - :members: - :member-order: groupwise - :inherited-members: - -ExceptionData class ----------------------- -.. autoclass:: applicationinsights.channel.contracts.ExceptionData - :members: - :member-order: groupwise - :inherited-members: - -ExceptionDetails class ----------------------- -.. autoclass:: applicationinsights.channel.contracts.ExceptionDetails - :members: - :member-order: groupwise - :inherited-members: - -Internal class --------------- -.. autoclass:: applicationinsights.channel.contracts.Internal - :members: - :member-order: groupwise - :inherited-members: - -Location class --------------- -.. autoclass:: applicationinsights.channel.contracts.Location - :members: - :member-order: groupwise - :inherited-members: - -MessageData class ------------------ -.. autoclass:: applicationinsights.channel.contracts.MessageData - :members: - :member-order: groupwise - :inherited-members: - -MetricData class ----------------- -.. autoclass:: applicationinsights.channel.contracts.MetricData - :members: - :member-order: groupwise - :inherited-members: - -Operation class ---------------- -.. autoclass:: applicationinsights.channel.contracts.Operation - :members: - :member-order: groupwise - :inherited-members: - -PageViewData class ------------------- -.. autoclass:: applicationinsights.channel.contracts.PageViewData - :members: - :member-order: groupwise - :inherited-members: - -RemoteDependencyData class --------------------------- -.. autoclass:: applicationinsights.channel.contracts.RemoteDependencyData - :members: - :member-order: groupwise - :inherited-members: - -RequestData class ------------------ -.. autoclass:: applicationinsights.channel.contracts.RequestData - :members: - :member-order: groupwise - :inherited-members: - -Session class -------------- -.. autoclass:: applicationinsights.channel.contracts.Session - :members: - :member-order: groupwise - :inherited-members: - -SeverityLevel class -------------------- -.. autoclass:: applicationinsights.channel.contracts.SeverityLevel - :members: - :member-order: groupwise - :inherited-members: - -StackFrame class ----------------- -.. autoclass:: applicationinsights.channel.contracts.StackFrame - :members: - :member-order: groupwise - :inherited-members: - -User class ----------- -.. autoclass:: applicationinsights.channel.contracts.User - :members: - :member-order: groupwise - :inherited-members: diff --git a/doc/applicationinsights.channel.rst b/doc/applicationinsights.channel.rst deleted file mode 100644 index 8a92eb9c..00000000 --- a/doc/applicationinsights.channel.rst +++ /dev/null @@ -1,65 +0,0 @@ -.. toctree:: - :maxdepth: 2 - :hidden: - - applicationinsights.channel.contracts - -applicationinsights.channel module -================================== - -SynchronousQueue class ----------------------- -.. autoclass:: applicationinsights.channel.SynchronousQueue - :members: - :member-order: groupwise - :inherited-members: - -SynchronousSender class ------------------------ -.. autoclass:: applicationinsights.channel.SynchronousSender - :members: - :member-order: groupwise - :inherited-members: - -AsynchronousQueue class ------------------------ -.. autoclass:: applicationinsights.channel.AsynchronousQueue - :members: - :member-order: groupwise - :inherited-members: - -AsynchronousSender class ------------------------- -.. autoclass:: applicationinsights.channel.AsynchronousSender - :members: - :member-order: groupwise - :inherited-members: - -QueueBase class ---------------- -.. autoclass:: applicationinsights.channel.QueueBase - :members: - :member-order: groupwise - :inherited-members: - -SenderBase class ----------------- -.. autoclass:: applicationinsights.channel.SenderBase - :members: - :member-order: groupwise - :inherited-members: - -TelemetryChannel class ----------------------- -.. automodule:: applicationinsights.channel.TelemetryChannel - :members: - :member-order: groupwise - :inherited-members: - -TelemetryContext class ----------------------- -.. autoclass:: applicationinsights.channel.TelemetryContext - :members: - :member-order: groupwise - :inherited-members: - diff --git a/doc/applicationinsights.django.rst b/doc/applicationinsights.django.rst deleted file mode 100644 index 0a1a41f3..00000000 --- a/doc/applicationinsights.django.rst +++ /dev/null @@ -1,21 +0,0 @@ -.. toctree:: - :maxdepth: 2 - :hidden: - -applicationinsights.django module -================================= - -ApplicationInsightsMiddleware class ------------------------------------ -.. autoclass:: applicationinsights.django.ApplicationInsightsMiddleware - :members: - :member-order: groupwise - :inherited-members: - -LoggingHandler class --------------------- -.. autoclass:: applicationinsights.django.LoggingHandler - -create_client function ----------------------- -.. autofunction:: applicationinsights.django.create_client diff --git a/doc/applicationinsights.exceptions.rst b/doc/applicationinsights.exceptions.rst deleted file mode 100644 index d9383b58..00000000 --- a/doc/applicationinsights.exceptions.rst +++ /dev/null @@ -1,10 +0,0 @@ -.. toctree:: - :maxdepth: 2 - :hidden: - -applicationinsights.exceptions module -===================================== - -enable function ---------------- -.. autofunction:: applicationinsights.exceptions.enable diff --git a/doc/applicationinsights.logging.rst b/doc/applicationinsights.logging.rst deleted file mode 100644 index 5c5a9c39..00000000 --- a/doc/applicationinsights.logging.rst +++ /dev/null @@ -1,17 +0,0 @@ -.. toctree:: - :maxdepth: 2 - :hidden: - -applicationinsights.logging module -================================== - -enable function ---------------- -.. autofunction:: applicationinsights.logging.enable - -LoggingHandler class --------------------- -.. autoclass:: applicationinsights.logging.LoggingHandler - :members: - :member-order: groupwise - :inherited-members: diff --git a/doc/applicationinsights.requests.rst b/doc/applicationinsights.requests.rst deleted file mode 100644 index b91a6b17..00000000 --- a/doc/applicationinsights.requests.rst +++ /dev/null @@ -1,13 +0,0 @@ -.. toctree:: - :maxdepth: 2 - :hidden: - -applicationinsights.requests module -=================================== - -WSGIApplication class ---------------------- -.. autoclass:: applicationinsights.requests.WSGIApplication - :members: - :member-order: groupwise - :inherited-members: diff --git a/doc/applicationinsights.rst b/doc/applicationinsights.rst deleted file mode 100644 index ae01d17a..00000000 --- a/doc/applicationinsights.rst +++ /dev/null @@ -1,18 +0,0 @@ -applicationinsights module -========================== - -.. toctree:: - :maxdepth: 1 - - applicationinsights.channel - applicationinsights.logging - applicationinsights.requests - applicationinsights.django - applicationinsights.exceptions - -TelemetryClient class ----------------------- -.. autoclass:: applicationinsights.TelemetryClient - :members: - :member-order: groupwise - :inherited-members: diff --git a/doc/conf.py b/doc/conf.py deleted file mode 100644 index e9c2b39c..00000000 --- a/doc/conf.py +++ /dev/null @@ -1,287 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -# -# Application Insights SDK for Python documentation build configuration file, created by -# sphinx-quickstart on Mon Dec 22 23:32:45 2014. -# -# This file is execfile()d with the current directory set to its -# containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. - -import sys -import os - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -#sys.path.insert(0, os.path.abspath('.')) - -# -- General configuration ------------------------------------------------ - -# If your documentation needs a minimal Sphinx version, state it here. -#needs_sphinx = '1.0' - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = [ - 'sphinx.ext.autodoc', - 'sphinx.ext.intersphinx', - 'sphinx.ext.todo', - 'sphinx.ext.coverage', - 'sphinx.ext.ifconfig', - 'sphinx.ext.viewcode', -] - -# Add any paths that contain templates here, relative to this directory. -templates_path = [ 'templates' ] - -# The suffix of source filenames. -source_suffix = '.rst' - -# The encoding of source files. -#source_encoding = 'utf-8-sig' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -project = 'Application Insights SDK for Python' -copyright = '2018, Microsoft' - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The short X.Y version. -version = '0.11.10' -# The full version, including alpha/beta/rc tags. -release = '0.11.10' - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -# -# This is also used if you do content translation via gettext catalogs. -# Usually you set "language" from the command line for these cases. -language = None - -# There are two options for replacing |today|: either, you set today to some -# non-false value, then it is used: -#today = '' -# Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -exclude_patterns = [ 'build' ] - -# The reST default role (used for this markup: `text`) to use for all -# documents. -#default_role = None - -# If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -#add_module_names = True - -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -#show_authors = False - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' - -# A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] - -# If true, keep warnings as "system message" paragraphs in the built documents. -#keep_warnings = False - - -# -- Options for HTML output ---------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -html_theme = 'default' - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -#html_theme_options = {} - -# Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] - -# The name for this set of Sphinx documents. If None, it defaults to -# " v documentation". -#html_title = None - -# A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -#html_logo = None - -# The name of an image file (within the static path) to use as favicon of the -# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -#html_favicon = None - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = [ 'static' ] - -# Add any extra paths that contain custom files (such as robots.txt or -# .htaccess) here, relative to this directory. These files are copied -# directly to the root of the documentation. -#html_extra_path = [] - -# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, -# using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -#html_use_smartypants = True - -# Custom sidebar templates, maps document names to template names. -#html_sidebars = {} - -# Additional templates that should be rendered to pages, maps page names to -# template names. -#html_additional_pages = {} - -# If false, no module index is generated. -html_domain_indices = False - -# If false, no index is generated. -#html_use_index = True - -# If true, the index is split into individual pages for each letter. -#html_split_index = False - -# If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True - -# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -#html_show_sphinx = True - -# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a tag referring to it. The value of this option must be the -# base URL from which the finished HTML is served. -#html_use_opensearch = '' - -# This is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = None - -# Language to be used for generating the HTML full-text search index. -# Sphinx supports the following languages: -# 'da', 'de', 'en', 'es', 'fi', 'fr', 'h', 'it', 'ja' -# 'nl', 'no', 'pt', 'ro', 'r', 'sv', 'tr' -#html_search_language = 'en' - -# A dictionary with options for the search language support, empty by default. -# Now only 'ja' uses this config value -#html_search_options = {'type': 'default'} - -# The name of a javascript file (relative to the configuration directory) that -# implements a search results scorer. If empty, the default will be used. -#html_search_scorer = 'scorer.js' - -# Output file base name for HTML help builder. -htmlhelp_basename = 'ApplicationInsightsSDKforPythondoc' - -# -- Options for LaTeX output --------------------------------------------- - -latex_elements = { -# The paper size ('letterpaper' or 'a4paper'). -#'papersize': 'letterpaper', - -# The font size ('10pt', '11pt' or '12pt'). -#'pointsize': '10pt', - -# Additional stuff for the LaTeX preamble. -#'preamble': '', - -# Latex figure (float) alignment -#'figure_align': 'htbp', -} - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, -# author, documentclass [howto, manual, or own class]). -latex_documents = [ - ('index', 'ApplicationInsightsSDKforPython.tex', 'Application Insights SDK for Python Documentation', 'Microsoft', 'manual'), -] - -# The name of an image file (relative to this directory) to place at the top of -# the title page. -#latex_logo = None - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -#latex_use_parts = False - -# If true, show page references after internal links. -#latex_show_pagerefs = False - -# If true, show URL addresses after external links. -#latex_show_urls = False - -# Documents to append as an appendix to all manuals. -#latex_appendices = [] - -# If false, no module index is generated. -#latex_domain_indices = True - - -# -- Options for manual page output --------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - ('index', 'applicationinsightssdkforpython', 'Application Insights SDK for Python Documentation', ['Microsoft'], 1) -] - -# If true, show URL addresses after external links. -#man_show_urls = False - - -# -- Options for Texinfo output ------------------------------------------- - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - ('index', 'ApplicationInsightsSDKforPython', 'Application Insights SDK for Python Documentation', - 'Microsoft', 'ApplicationInsightsSDKforPython', 'One line description of project.', - 'Miscellaneous'), -] - -# Documents to append as an appendix to all manuals. -#texinfo_appendices = [] - -# If false, no module index is generated. -#texinfo_domain_indices = True - -# How to display URL addresses: 'footnote', 'no', or 'inline'. -#texinfo_show_urls = 'footnote' - -# If true, do not generate a @detailmenu in the "Top" node's menu. -#texinfo_no_detailmenu = False - - -# Example configuration for intersphinx: refer to the Python standard library. -intersphinx_mapping = {'http://docs.python.org/': None} diff --git a/doc/index.rst b/doc/index.rst deleted file mode 100644 index 6c4e0719..00000000 --- a/doc/index.rst +++ /dev/null @@ -1,406 +0,0 @@ -.. toctree:: - :maxdepth: 2 - :hidden: - - applicationinsights - -Application Insights SDK for Python -=================================== - -.. sidebar:: Usage - - Once installed, you can send telemetry to Application Insights. Here are a few samples. - - * :ref:`Sending a simple event telemetry item ` - * :ref:`Sending an event telemetry item with custom properties and measurements ` - * :ref:`Sending a trace telemetry item with custom properties ` - * :ref:`Sending a metric telemetry item ` - * :ref:`Sending an exception telemetry item with custom properties and measurements ` - * :ref:`Configuring context for a telemetry client instance ` - * :ref:`Configuring channel related properties ` - * :ref:`Configuring synchronous (default) channel properties ` - * :ref:`Configuring an asynchronous channel instead of the synchronous default ` - * :ref:`Configuring asynchronous channel properties ` - * :ref:`Basic logging configuration (first option) ` - * :ref:`Basic logging configuration (second option) ` - * :ref:`Advanced logging configuration ` - * :ref:`Logging unhandled exceptions ` - * :ref:`Logging requests ` - * :ref:`Integrating with Django ` - -This project extends the Application Insights API surface to support Python. `Application -Insights `__ is a service that allows developers to keep their application available, performing and succeeding. This Python module will allow you to send telemetry of various kinds (event, trace, exception, etc.) to the Application Insights service where they can be visualized in the Azure Portal. - -Requirements ------------- - -Python 2.7 and Python 3.4 are currently supported by this module. - -For opening the project in Microsoft Visual Studio you will need `Python Tools for Visual Studio `__. - -Installation ------------- - -To install the latest release you can use `pip `__. - -:: - - $ pip install applicationinsights - -Usage ------ - -Once installed, you can send telemetry to Application Insights. Here are a few samples. - - **Note**: before you can send data to you will need an instrumentation key. Please see the `Getting an Application Insights - Instrumentation Key `__ - section for more information. - -.. _usage-sample-01: - -**Sending a simple event telemetry item** - -.. code:: python - - from applicationinsights import TelemetryClient - tc = TelemetryClient('') - tc.track_event("Test event") - tc.flush() - -.. _usage-sample-02: - -**Sending an event telemetry item with custom properties and measurements** - -.. code:: python - - from applicationinsights import TelemetryClient - tc = TelemetryClient('') - tc.track_event('Test event', { 'foo': 'bar' }, { 'baz': 42 }) - tc.flush() - -.. _usage-sample-03: - -**Sending a trace telemetry item with custom properties** - -.. code:: python - - from applicationinsights import TelemetryClient - tc = TelemetryClient('') - tc.track_trace('Test trace', { 'foo': 'bar' }) - tc.flush() - -.. _usage-sample-04: - -**Sending a metric telemetry item** - -.. code:: python - - from applicationinsights import TelemetryClient - tc = TelemetryClient('') - tc.track_metric('My Metric', 42) - tc.flush() - -.. _usage-sample-05: - -**Sending an exception telemetry item with custom properties and measurements** - -.. code:: python - - import sys - from applicationinsights import TelemetryClient - tc = TelemetryClient('') - try: - raise Exception('blah') - except: - tc.track_exception() - - try: - raise Exception("blah") - except: - tc.track_exception(*sys.exc_info(), properties={ 'foo': 'bar' }, measurements={ 'x': 42 }) - - tc.flush() - -.. _usage-sample-06: - -**Configuring context for a telemetry client instance** - -.. code:: python - - from applicationinsights import TelemetryClient - tc = TelemetryClient('') - tc.context.application.ver = '1.2.3' - tc.context.device.id = 'My current device' - tc.context.device.oem_name = 'Asus' - tc.context.device.model = 'X31A' - tc.context.device.type = "Other" - tc.context.user.id = 'santa@northpole.net' - tc.track_trace('My trace with context') - tc.flush() - -.. _usage-sample-07: - -**Configuring channel related properties** - -.. code:: python - - from applicationinsights import TelemetryClient - tc = TelemetryClient('') - # flush telemetry every 30 seconds (assuming we don't hit max_queue_item_count first) - tc.channel.sender.send_interval_in_milliseconds = 30 * 1000 - # flush telemetry if we have 10 or more telemetry items in our queue - tc.channel.queue.max_queue_length = 10 - -.. _usage-sample-08: - -**Configuring synchronous (default) channel properties** - -.. code:: python - - from applicationinsights import TelemetryClient - tc = TelemetryClient('') - # flush telemetry if we have 10 or more telemetry items in our queue - tc.channel.queue.max_queue_length = 10 - # send telemetry to the service in batches of 5 - tc.channel.sender.send_buffer_size = 5 - -.. _usage-sample-09: - -**Configuring an asynchronous channel instead of the synchronous default** - -.. code:: python - - from applicationinsights import TelemetryClient, channel - sender = channel.AsynchronousSender() - queue = channel.AsynchronousQueue(sender) - channel = channel::TelemetryChannel(None, queue) - tc = TelemetryClient('', channel) - # Note: the event will be sent on a separate thread; if the app finishes before - # the thread finishes, the data is lost - tc.track_event('My event') - -.. _usage-sample-10: - -**Configuring asynchronous channel properties** - -.. code:: python - - from applicationinsights import TelemetryClient, channel - sender = channel.AsynchronousSender() - queue = channel.AsynchronousQueue(sender) - channel = channel::TelemetryChannel(None, queue) - tc = TelemetryClient('', channel) - # flush telemetry if we have 10 or more telemetry items in our queue - tc.channel.queue.max_queue_length = 10 - # send telemetry to the service in batches of 5 - tc.channel.sender.send_buffer_size = 5 - # the background worker thread will be active for 5 seconds before it shuts down. if - # during this time items are picked up from the queue, the timer is reset. - tc.channel.sender.send_time = 5 - # the background worker thread will poll the queue every 0.5 seconds for new items - tc.channel.sender.send_interval = 0.5 - -.. _usage-sample-11: - -**Basic logging configuration (first option)** - -.. code:: python - - import logging - from applicationinsights.logging import enable - - # set up logging - enable('') - - # log something (this will be sent to the Application Insights service as a trace) - logging.info('This is a message') - - # logging shutdown will cause a flush of all un-sent telemetry items - # alternatively flush manually via handler.flush() - -.. _usage-sample-12: - -**Basic logging configuration (second option)** - -.. code:: python - - import logging - from applicationinsights.logging import LoggingHandler - - # set up logging - handler = LoggingHandler('') - logging.basicConfig(handlers=[ handler ], format='%(levelname)s: %(message)s', level=logging.DEBUG) - - # log something (this will be sent to the Application Insights service as a trace) - logging.debug('This is a message') - - try: - raise Exception('Some exception') - except: - # this will send an exception to the Application Insights service - logging.exception('Code went boom!') - - # logging shutdown will cause a flush of all un-sent telemetry items - # alternatively flush manually via handler.flush() - -.. _usage-sample-13: - -**Advanced logging configuration** - -.. code:: python - - import logging - from applicationinsights.logging import LoggingHandler - - # set up logging - handler = LoggingHandler('') - handler.setLevel(logging.DEBUG) - handler.setFormatter(logging.Formatter('%(levelname)s: %(message)s')) - my_logger = logging.getLogger('simple_logger') - my_logger.setLevel(logging.DEBUG) - my_logger.addHandler(handler) - - # log something (this will be sent to the Application Insights service as a trace) - my_logger.debug('This is a message') - - # logging shutdown will cause a flush of all un-sent telemetry items - # alternatively flush manually via handler.flush() - -.. _usage-sample-14: - -**Logging unhandled exceptions** - -.. code:: python - - from applicationinsights.exceptions import enable - - # set up exception capture - enable('') - - # raise an exception (this will be sent to the Application Insights service as an exception telemetry object) - raise Exception('Boom!') - -.. _usage-sample-15: - -**Logging requests** - -.. code:: python - - from flask import Flask - from applicationinsights.requests import WSGIApplication - - # instantiate the Flask application and wrap its WSGI application - app = Flask(__name__) - app.wsgi_app = WSGIApplication('', app.wsgi_app) - - # define a simple route - @app.route('/') - def hello_world(): - return 'Hello World!' - - # run the application - if __name__ == '__main__': - app.run() - -.. _usage-sample-16: - -**Integrating with Django** - -Place the following in your `settings.py` file: - -.. code:: python - - # If on Django < 1.10 - MIDDLEWARE_CLASSES = [ - # ... or whatever is below for you ... - 'django.middleware.security.SecurityMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.middleware.common.CommonMiddleware', - 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', - 'django.middleware.clickjacking.XFrameOptionsMiddleware', - # ... or whatever is above for you ... - 'applicationinsights.django.ApplicationInsightsMiddleware', # Add this middleware to the end - ] - - # If on Django >= 1.10 - MIDDLEWARE = [ - # ... or whatever is below for you ... - 'django.middleware.security.SecurityMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.middleware.common.CommonMiddleware', - 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', - 'django.middleware.clickjacking.XFrameOptionsMiddleware', - # ... or whatever is above for you ... - 'applicationinsights.django.ApplicationInsightsMiddleware', # Add this middleware to the end - ] - - APPLICATION_INSIGHTS = { - # (required) Your Application Insights instrumentation key - 'ikey': "00000000-0000-0000-0000-000000000000", - - # (optional) By default, request names are logged as the fully-qualified - # name of the view. To disable this behavior, specify: - 'use_operation_url': True, - - # (optional) By default, arguments to views are tracked as custom - # properties. To disable this, specify: - 'record_view_arguments': False, - - # (optional) Events are submitted to Application Insights asynchronously. - # send_interval specifies how often the queue is checked for items to submit. - # send_time specifies how long the sender waits for new input before recycling - # the background thread. - 'send_interval': 1.0, # Check every second - 'send_time': 3.0, # Wait up to 3 seconds for an event - - # (optional, uncommon) If you must send to an endpoint other than the - # default endpoint, specify it here: - 'endpoint': "https://dc.services.visualstudio.com/v2/track", - } - -This will log all requests and exceptions to the instrumentation key -specified in the `APPLICATION_INSIGHTS` setting. In addition, an -`appinsights` property will be placed on each incoming `request` object in -your views. This will have the following properties: - -* `client`: This is an instance of the :class:`applicationinsights.TelemetryClient` type, which will - submit telemetry to the same instrumentation key, and will parent each telemetry item to the current - request. -* `request`: This is the :class:`applicationinsights.channel.contracts.RequestData` instance for the - current request. You can modify properties on this object during the handling of the current request. - It will be submitted when the request has finished. -* `context`: This is the :class:`applicationinsights.channel.TelemetryContext` object for the current - ApplicationInsights sender. - -You can also hook up logging to Django. For example, to log all builtin -Django warnings and errors, use the following logging configuration in -`settings.py`: - -.. code:: python - - LOGGING = { - 'version': 1, - 'disable_existing_loggers': False, - 'handlers': { - # The application insights handler is here - 'appinsights': { - 'class': 'applicationinsights.django.LoggingHandler', - 'level': 'WARNING' - } - }, - 'loggers': { - 'django': { - 'handlers': ['appinsights'], - 'level': 'WARNING', - 'propagate': True, - } - } - } - -See Django's logging documentation for more information: -https://docs.djangoproject.com/en/1.11/topics/logging/ diff --git a/doc/make.bat b/doc/make.bat deleted file mode 100644 index 3d0fecfe..00000000 --- a/doc/make.bat +++ /dev/null @@ -1,263 +0,0 @@ -@ECHO OFF - -REM Command file for Sphinx documentation - -if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build -) -set BUILDDIR=build -set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . -set I18NSPHINXOPTS=%SPHINXOPTS% . -if NOT "%PAPER%" == "" ( - set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% - set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% -) - -if "%1" == "" goto help - -if "%1" == "help" ( - :help - echo.Please use `make ^` where ^ is one of - echo. html to make standalone HTML files - echo. dirhtml to make HTML files named index.html in directories - echo. singlehtml to make a single large HTML file - echo. pickle to make pickle files - echo. json to make JSON files - echo. htmlhelp to make HTML files and a HTML help project - echo. qthelp to make HTML files and a qthelp project - echo. devhelp to make HTML files and a Devhelp project - echo. epub to make an epub - echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter - echo. text to make text files - echo. man to make manual pages - echo. texinfo to make Texinfo files - echo. gettext to make PO message catalogs - echo. changes to make an overview over all changed/added/deprecated items - echo. xml to make Docutils-native XML files - echo. pseudoxml to make pseudoxml-XML files for display purposes - echo. linkcheck to check all external links for integrity - echo. doctest to run all doctests embedded in the documentation if enabled - echo. coverage to run coverage check of the documentation if enabled - goto end -) - -if "%1" == "clean" ( - for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i - del /q /s %BUILDDIR%\* - goto end -) - - -REM Check if sphinx-build is available and fallback to Python version if any -%SPHINXBUILD% 2> nul -if errorlevel 9009 goto sphinx_python -goto sphinx_ok - -:sphinx_python - -set SPHINXBUILD=python -m sphinx.__init__ -%SPHINXBUILD% 2> nul -if errorlevel 9009 ( - echo. - echo.The 'sphinx-build' command was not found. Make sure you have Sphinx - echo.installed, then set the SPHINXBUILD environment variable to point - echo.to the full path of the 'sphinx-build' executable. Alternatively you - echo.may add the Sphinx directory to PATH. - echo. - echo.If you don't have Sphinx installed, grab it from - echo.http://sphinx-doc.org/ - exit /b 1 -) - -:sphinx_ok - - -if "%1" == "html" ( - %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/html. - goto end -) - -if "%1" == "dirhtml" ( - %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. - goto end -) - -if "%1" == "singlehtml" ( - %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. - goto end -) - -if "%1" == "pickle" ( - %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can process the pickle files. - goto end -) - -if "%1" == "json" ( - %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can process the JSON files. - goto end -) - -if "%1" == "htmlhelp" ( - %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can run HTML Help Workshop with the ^ -.hhp project file in %BUILDDIR%/htmlhelp. - goto end -) - -if "%1" == "qthelp" ( - %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can run "qcollectiongenerator" with the ^ -.qhcp project file in %BUILDDIR%/qthelp, like this: - echo.^> qcollectiongenerator %BUILDDIR%\qthelp\ApplicationInsightsSDKforPython.qhcp - echo.To view the help file: - echo.^> assistant -collectionFile %BUILDDIR%\qthelp\ApplicationInsightsSDKforPython.ghc - goto end -) - -if "%1" == "devhelp" ( - %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. - goto end -) - -if "%1" == "epub" ( - %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The epub file is in %BUILDDIR%/epub. - goto end -) - -if "%1" == "latex" ( - %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. - goto end -) - -if "%1" == "latexpdf" ( - %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex - cd %BUILDDIR%/latex - make all-pdf - cd %~dp0 - echo. - echo.Build finished; the PDF files are in %BUILDDIR%/latex. - goto end -) - -if "%1" == "latexpdfja" ( - %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex - cd %BUILDDIR%/latex - make all-pdf-ja - cd %~dp0 - echo. - echo.Build finished; the PDF files are in %BUILDDIR%/latex. - goto end -) - -if "%1" == "text" ( - %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The text files are in %BUILDDIR%/text. - goto end -) - -if "%1" == "man" ( - %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The manual pages are in %BUILDDIR%/man. - goto end -) - -if "%1" == "texinfo" ( - %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. - goto end -) - -if "%1" == "gettext" ( - %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The message catalogs are in %BUILDDIR%/locale. - goto end -) - -if "%1" == "changes" ( - %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes - if errorlevel 1 exit /b 1 - echo. - echo.The overview file is in %BUILDDIR%/changes. - goto end -) - -if "%1" == "linkcheck" ( - %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck - if errorlevel 1 exit /b 1 - echo. - echo.Link check complete; look for any errors in the above output ^ -or in %BUILDDIR%/linkcheck/output.txt. - goto end -) - -if "%1" == "doctest" ( - %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest - if errorlevel 1 exit /b 1 - echo. - echo.Testing of doctests in the sources finished, look at the ^ -results in %BUILDDIR%/doctest/output.txt. - goto end -) - -if "%1" == "coverage" ( - %SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage - if errorlevel 1 exit /b 1 - echo. - echo.Testing of coverage in the sources finished, look at the ^ -results in %BUILDDIR%/coverage/python.txt. - goto end -) - -if "%1" == "xml" ( - %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The XML files are in %BUILDDIR%/xml. - goto end -) - -if "%1" == "pseudoxml" ( - %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. - goto end -) - -:end diff --git a/doc/static/overrides.css b/doc/static/overrides.css deleted file mode 100644 index b1725abd..00000000 --- a/doc/static/overrides.css +++ /dev/null @@ -1,15 +0,0 @@ -div.bodywrapper { - margin: 0px 0px 0px 265px; -} - -div.sphinxsidebar { - width: 265px; -} - -div.sphinxsidebar #searchbox input[type="text"] { - width: 205px; -} - -dl.method dl.docutils dd p { - margin-bottom: 0; -} \ No newline at end of file diff --git a/doc/templates/layout.html b/doc/templates/layout.html deleted file mode 100644 index e19ed680..00000000 --- a/doc/templates/layout.html +++ /dev/null @@ -1,5 +0,0 @@ -{# layout.html #} -{# Import the theme's layout. #} -{% extends "!layout.html" %} - -{% set css_files = css_files + [ '_static/overrides.css' ] %} \ No newline at end of file diff --git a/lint-requirements.txt b/lint-requirements.txt new file mode 100644 index 00000000..445e5436 --- /dev/null +++ b/lint-requirements.txt @@ -0,0 +1,4 @@ +isort +black +pylint +flake8 diff --git a/setup.cfg b/setup.cfg index 9bd8e915..9f771f58 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,5 +1,38 @@ -[bdist_wheel] -# This flag says that the code is written to work on both Python 2 and Python -# 3. If at all possible, it is good practice to do this. If you cannot, you -# will need to generate wheels for each Python version that you support. -universal=1 \ No newline at end of file +# ------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License in the project root for +# license information. +# -------------------------------------------------------------------------- +[metadata] +name = azure-monitor-opentelemetry-distro +description = Azure Monitor Distro for OpenTelemetry Python +long_description = file: README.md +long_description_content_type = text/markdown +author = Microsoft Corporation +url = https://github.com/microsoft/ApplicationInsights-Python +platforms = any +license = MIT License +classifiers = + Development Status :: 4 - Beta + Programming Language :: Python + Programming Language :: Python :: 3 + Programming Language :: Python :: 3.6 + Programming Language :: Python :: 3.7 + Programming Language :: Python :: 3.8 + Programming Language :: Python :: 3.9 + Programming Language :: Python :: 3.10 + License :: OSI Approved :: MIT License + Typing :: Typed + +[options] +python_requires = >=3.6 +package_dir= + =src +packages=find_namespace: +zip_safe = False +include_package_data = True +install_requires = + azure-monitor-opentelemetry-exporter == 1.0.0b7 + +[options.packages.find] +where = src diff --git a/setup.py b/setup.py index bd2012c6..f4bbcc43 100644 --- a/setup.py +++ b/setup.py @@ -1,68 +1,21 @@ -from setuptools import setup, find_packages # Always prefer setuptools over distutils -from codecs import open # To use a consistent encoding -from os import path +# ------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License in the project root for +# license information. +# -------------------------------------------------------------------------- -here = path.abspath(path.dirname(__file__)) +import os -# Get the long description from the relevant file -with open(path.join(here, 'README.rst'), encoding='utf-8') as f: - long_description = f.read() +import setuptools -setup( - name='applicationinsights', - - # Versions should comply with PEP440. For a discussion on single-sourcing - # the version across setup.py and the project code, see - # http://packaging.python.org/en/latest/tutorial.html#version - version='0.11.10', - - description='This project extends the Application Insights API surface to support Python.', - long_description=long_description, - - # The project's main homepage. - url='https://github.com/Microsoft/ApplicationInsights-Python', - download_url='https://github.com/Microsoft/ApplicationInsights-Python', - - # Author details - author='Microsoft', - author_email='appinsightssdk@microsoft.com', - - # Choose your license - license='MIT', - - # See https://pypi.python.org/pypi?%3Aaction=list_classifiers - classifiers=[ - # How mature is this project? Common values are - # 3 - Alpha - # 4 - Beta - # 5 - Production/Stable - 'Development Status :: 3 - Alpha', - - # Indicate who your project is intended for - 'Intended Audience :: Developers', - 'Topic :: Software Development :: Libraries :: Python Modules', - - # operating systems - 'Operating System :: OS Independent', - - # Pick your license as you wish (should match "license" above) - 'License :: OSI Approved :: MIT License', - - # Specify the Python versions you support here. In particular, ensure - # that you indicate whether you support Python 2, Python 3 or both. - 'Programming Language :: Python :: 2.7', - 'Programming Language :: Python :: 3.4', - 'Programming Language :: Python :: 3.5', - 'Programming Language :: Python :: 3.6', - ], - - # What does your project relate to? - keywords='analytics applicationinsights telemetry appinsights development', - - # You can just specify the packages manually here if your project is - # simple. Or you can use find_packages(). - packages=find_packages(exclude=['contrib', 'docs', 'tests*']), - - test_suite='tests.applicationinsights_tests' +BASE_DIR = os.path.dirname(__file__) +VERSION_FILENAME = os.path.join( + BASE_DIR, "src", "azure", "monitor", "opentelemetry", "distro", "version.py" ) +PACKAGE_INFO = {} +with open(VERSION_FILENAME, encoding="utf-8") as f: + exec(f.read(), PACKAGE_INFO) +setuptools.setup( + version=PACKAGE_INFO["__version__"], +) diff --git a/src/azure/monitor/opentelemetry/distro/version.py b/src/azure/monitor/opentelemetry/distro/version.py new file mode 100644 index 00000000..f7f75f7a --- /dev/null +++ b/src/azure/monitor/opentelemetry/distro/version.py @@ -0,0 +1,7 @@ +# ------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License in the project root for +# license information. +# -------------------------------------------------------------------------- + +VERSION = "1.0.0b7" diff --git a/test-requirements.txt b/test-requirements.txt new file mode 100644 index 00000000..31db64ad --- /dev/null +++ b/test-requirements.txt @@ -0,0 +1,2 @@ +pytest +azure-monitor-opentelemetry-exporter diff --git a/tests/__init__.py b/tests/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/tests/applicationinsights_tests/TestTelemetryClient.py b/tests/applicationinsights_tests/TestTelemetryClient.py deleted file mode 100644 index fef52d3a..00000000 --- a/tests/applicationinsights_tests/TestTelemetryClient.py +++ /dev/null @@ -1,261 +0,0 @@ -import unittest -import inspect -import json -import sys - -if sys.version_info < (3,0): - from test import test_support -else: - from test import support as test_support - -import os, os.path -rootDirectory = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', '..') -if rootDirectory not in sys.path: - sys.path.append(rootDirectory) - -from applicationinsights import TelemetryClient, channel - - -class TestTelemetryClient(unittest.TestCase): - def test_constructor_throws_with_no_instrumentation_key(self): - self.assertRaises(Exception, TelemetryClient, None) - - def test_constructor_sets_instrumentation_key(self): - client = TelemetryClient('foo') - self.assertEqual('foo', client.context.instrumentation_key) - - def test_constructor_maintains_backwards_compatibility_when_specifying_only_telemetry_channel(self): - expected = channel.TelemetryChannel() - client = TelemetryClient(expected) - self.assertEqual(expected, client.channel) - self.assertIsNone(client.context.instrumentation_key) - - def test_context_property_works_as_expected(self): - client = TelemetryClient('foo') - self.assertIsNotNone(client.context) - - def test_channel_property_works_as_expected(self): - expected = channel.TelemetryChannel() - client = TelemetryClient('foo', expected) - self.assertEqual(expected, client.channel) - - def test_track_event_works_as_expected(self): - sender = MockTelemetrySender() - queue = channel.SynchronousQueue(sender) - client = TelemetryClient('99999999-9999-9999-9999-999999999999', channel.TelemetryChannel(context=None, queue=queue)) - client.context.device = None - client.track_event('test', { 'foo': 'bar' }, { 'x': 42 }) - client.flush() - expected = '{"ver": 1, "name": "Microsoft.ApplicationInsights.Event", "time": "TIME_PLACEHOLDER", "sampleRate": 100.0, "iKey": "99999999-9999-9999-9999-999999999999", "tags": {"ai.device.id": "DEVICE_ID_PLACEHOLDER", "ai.device.locale": "DEVICE_LOCALE_PLACEHOLDER", "ai.device.osVersion": "DEVICE_OS_VERSION_PLACEHOLDER", "ai.device.type": "DEVICE_TYPE_PLACEHOLDER", "ai.internal.sdkVersion": "SDK_VERSION_PLACEHOLDER"}, "data": {"baseType": "EventData", "baseData": {"ver": 2, "name": "test", "properties": {"foo": "bar"}, "measurements": {"x": 42}}}}' - sender.data.time = 'TIME_PLACEHOLDER' - sender.data.tags['ai.internal.sdkVersion'] = 'SDK_VERSION_PLACEHOLDER' - sender.data.tags['ai.device.id'] = "DEVICE_ID_PLACEHOLDER" - sender.data.tags['ai.device.locale'] = "DEVICE_LOCALE_PLACEHOLDER" - sender.data.tags['ai.device.osVersion'] = "DEVICE_OS_VERSION_PLACEHOLDER" - sender.data.tags['ai.device.type'] = "DEVICE_TYPE_PLACEHOLDER" - actual = json.dumps(sender.data.write()) - self.maxDiff = None - self.assertEqual(expected, actual) - - def test_track_event_with_context_properties_works_as_expected(self): - sender = MockTelemetrySender() - queue = channel.SynchronousQueue(sender) - client = TelemetryClient('99999999-9999-9999-9999-999999999999', channel.TelemetryChannel(context=None, queue=queue)) - client.context.device = None - client.context.properties['foo'] = 'bar' - client.track_event('test') - client.flush() - expected = '{"ver": 1, "name": "Microsoft.ApplicationInsights.Event", "time": "TIME_PLACEHOLDER", "sampleRate": 100.0, "iKey": "99999999-9999-9999-9999-999999999999", "tags": {"ai.device.id": "DEVICE_ID_PLACEHOLDER", "ai.device.locale": "DEVICE_LOCALE_PLACEHOLDER", "ai.device.osVersion": "DEVICE_OS_VERSION_PLACEHOLDER", "ai.device.type": "DEVICE_TYPE_PLACEHOLDER", "ai.internal.sdkVersion": "SDK_VERSION_PLACEHOLDER"}, "data": {"baseType": "EventData", "baseData": {"ver": 2, "name": "test", "properties": {"foo": "bar"}}}}' - sender.data.time = 'TIME_PLACEHOLDER' - sender.data.tags['ai.internal.sdkVersion'] = 'SDK_VERSION_PLACEHOLDER' - sender.data.tags['ai.device.id'] = "DEVICE_ID_PLACEHOLDER" - sender.data.tags['ai.device.locale'] = "DEVICE_LOCALE_PLACEHOLDER" - sender.data.tags['ai.device.osVersion'] = "DEVICE_OS_VERSION_PLACEHOLDER" - sender.data.tags['ai.device.type'] = "DEVICE_TYPE_PLACEHOLDER" - actual = json.dumps(sender.data.write()) - self.maxDiff = None - self.assertEqual(expected, actual) - - def test_track_event_with_merged_context_properties_works_as_expected(self): - key = '99999999-9999-9999-9999-999999999999' - sender = MockTelemetrySender() - queue = channel.SynchronousQueue(sender) - - chan = channel.TelemetryChannel(queue=queue) - chan.context.properties['foo'] = 'bar' - - client1 = TelemetryClient(key, chan) - client1.context.device = None - client1.context.properties['x'] = 42 - - client2 = TelemetryClient(key, chan) - client2.context.device = None - client2.context.properties['x'] = 84 - - client1.track_event('test 1') - client1.flush() - sender.data.time = 'TIME_PLACEHOLDER' - sender.data.tags['ai.internal.sdkVersion'] = 'SDK_VERSION_PLACEHOLDER' - sender.data.tags['ai.device.id'] = "DEVICE_ID_PLACEHOLDER" - sender.data.tags['ai.device.locale'] = "DEVICE_LOCALE_PLACEHOLDER" - sender.data.tags['ai.device.osVersion'] = "DEVICE_OS_VERSION_PLACEHOLDER" - sender.data.tags['ai.device.type'] = "DEVICE_TYPE_PLACEHOLDER" - actual = json.dumps(sender.data.write()) - expected = '{"ver": 1, "name": "Microsoft.ApplicationInsights.Event", "time": "TIME_PLACEHOLDER", "sampleRate": 100.0, "iKey": "99999999-9999-9999-9999-999999999999", "tags": {"ai.device.id": "DEVICE_ID_PLACEHOLDER", "ai.device.locale": "DEVICE_LOCALE_PLACEHOLDER", "ai.device.osVersion": "DEVICE_OS_VERSION_PLACEHOLDER", "ai.device.type": "DEVICE_TYPE_PLACEHOLDER", "ai.internal.sdkVersion": "SDK_VERSION_PLACEHOLDER"}, "data": {"baseType": "EventData", "baseData": {"ver": 2, "name": "test 1", "properties": {"foo": "bar", "x": 42}}}}' - self.maxDiff = None - self.assertEqual(expected, actual) - - client2.track_event('test 2') - client2.flush() - sender.data.time = 'TIME_PLACEHOLDER' - sender.data.tags['ai.internal.sdkVersion'] = 'SDK_VERSION_PLACEHOLDER' - sender.data.tags['ai.device.id'] = "DEVICE_ID_PLACEHOLDER" - sender.data.tags['ai.device.locale'] = "DEVICE_LOCALE_PLACEHOLDER" - sender.data.tags['ai.device.osVersion'] = "DEVICE_OS_VERSION_PLACEHOLDER" - sender.data.tags['ai.device.type'] = "DEVICE_TYPE_PLACEHOLDER" - actual = json.dumps(sender.data.write()) - expected = '{"ver": 1, "name": "Microsoft.ApplicationInsights.Event", "time": "TIME_PLACEHOLDER", "sampleRate": 100.0, "iKey": "99999999-9999-9999-9999-999999999999", "tags": {"ai.device.id": "DEVICE_ID_PLACEHOLDER", "ai.device.locale": "DEVICE_LOCALE_PLACEHOLDER", "ai.device.osVersion": "DEVICE_OS_VERSION_PLACEHOLDER", "ai.device.type": "DEVICE_TYPE_PLACEHOLDER", "ai.internal.sdkVersion": "SDK_VERSION_PLACEHOLDER"}, "data": {"baseType": "EventData", "baseData": {"ver": 2, "name": "test 2", "properties": {"foo": "bar", "x": 84}}}}' - self.assertEqual(expected, actual) - - def test_track_metric_works_as_expected(self): - sender = MockTelemetrySender() - queue = channel.SynchronousQueue(sender) - client = TelemetryClient('99999999-9999-9999-9999-999999999999', channel.TelemetryChannel(context=None, queue=queue)) - client.context.device = None - client.track_metric('metric', 42, channel.contracts.DataPointType.aggregation, 13, 1, 123, 111, {'foo': 'bar'}) - client.flush() - expected = '{"ver": 1, "name": "Microsoft.ApplicationInsights.Metric", "time": "TIME_PLACEHOLDER", "sampleRate": 100.0, "iKey": "99999999-9999-9999-9999-999999999999", "tags": {"ai.device.id": "DEVICE_ID_PLACEHOLDER", "ai.device.locale": "DEVICE_LOCALE_PLACEHOLDER", "ai.device.osVersion": "DEVICE_OS_VERSION_PLACEHOLDER", "ai.device.type": "DEVICE_TYPE_PLACEHOLDER", "ai.internal.sdkVersion": "SDK_VERSION_PLACEHOLDER"}, "data": {"baseType": "MetricData", "baseData": {"ver": 2, "metrics": [{"name": "metric", "kind": 1, "value": 42, "count": 13, "min": 1, "max": 123, "stdDev": 111}], "properties": {"foo": "bar"}}}}' - sender.data.time = 'TIME_PLACEHOLDER' - sender.data.tags['ai.internal.sdkVersion'] = 'SDK_VERSION_PLACEHOLDER' - sender.data.tags['ai.device.id'] = "DEVICE_ID_PLACEHOLDER" - sender.data.tags['ai.device.locale'] = "DEVICE_LOCALE_PLACEHOLDER" - sender.data.tags['ai.device.osVersion'] = "DEVICE_OS_VERSION_PLACEHOLDER" - sender.data.tags['ai.device.type'] = "DEVICE_TYPE_PLACEHOLDER" - actual = json.dumps(sender.data.write()) - self.maxDiff = None - self.assertEqual(expected, actual) - - def test_track_trace_works_as_expected(self): - sender = MockTelemetrySender() - queue = channel.SynchronousQueue(sender) - client = TelemetryClient('99999999-9999-9999-9999-999999999999', channel.TelemetryChannel(context=None, queue=queue)) - client.context.device = None - client.track_trace('test', { 'foo': 'bar' }, severity='WARNING') - client.flush() - expected = '{"ver": 1, "name": "Microsoft.ApplicationInsights.Message", "time": "TIME_PLACEHOLDER", "sampleRate": 100.0, "iKey": "99999999-9999-9999-9999-999999999999", "tags": {"ai.device.id": "DEVICE_ID_PLACEHOLDER", "ai.device.locale": "DEVICE_LOCALE_PLACEHOLDER", "ai.device.osVersion": "DEVICE_OS_VERSION_PLACEHOLDER", "ai.device.type": "DEVICE_TYPE_PLACEHOLDER", "ai.internal.sdkVersion": "SDK_VERSION_PLACEHOLDER"}, "data": {"baseType": "MessageData", "baseData": {"ver": 2, "message": "test", "severityLevel": 2, "properties": {"foo": "bar"}}}}' - sender.data.time = 'TIME_PLACEHOLDER' - sender.data.tags['ai.internal.sdkVersion'] = 'SDK_VERSION_PLACEHOLDER' - sender.data.tags['ai.device.id'] = "DEVICE_ID_PLACEHOLDER" - sender.data.tags['ai.device.locale'] = "DEVICE_LOCALE_PLACEHOLDER" - sender.data.tags['ai.device.osVersion'] = "DEVICE_OS_VERSION_PLACEHOLDER" - sender.data.tags['ai.device.type'] = "DEVICE_TYPE_PLACEHOLDER" - actual = json.dumps(sender.data.write()) - self.maxDiff = None - self.assertEqual(expected, actual) - - def test_track_pageview_works_as_expected(self): - sender = MockTelemetrySender() - queue = channel.SynchronousQueue(sender) - client = TelemetryClient('99999999-9999-9999-9999-999999999999', channel.TelemetryChannel(context=None, queue=queue)) - client.context.device = None - client.track_pageview('test', 'http://tempuri.org', 13, { 'foo': 'bar' }, { 'x': 42 }) - client.flush() - expected = '{"ver": 1, "name": "Microsoft.ApplicationInsights.PageView", "time": "TIME_PLACEHOLDER", "sampleRate": 100.0, "iKey": "99999999-9999-9999-9999-999999999999", "tags": {"ai.device.id": "DEVICE_ID_PLACEHOLDER", "ai.device.locale": "DEVICE_LOCALE_PLACEHOLDER", "ai.device.osVersion": "DEVICE_OS_VERSION_PLACEHOLDER", "ai.device.type": "DEVICE_TYPE_PLACEHOLDER", "ai.internal.sdkVersion": "SDK_VERSION_PLACEHOLDER"}, "data": {"baseType": "PageViewData", "baseData": {"ver": 2, "url": "http://tempuri.org", "name": "test", "duration": 13, "properties": {"foo": "bar"}, "measurements": {"x": 42}}}}' - sender.data.time = 'TIME_PLACEHOLDER' - sender.data.tags['ai.internal.sdkVersion'] = 'SDK_VERSION_PLACEHOLDER' - sender.data.tags['ai.device.id'] = "DEVICE_ID_PLACEHOLDER" - sender.data.tags['ai.device.locale'] = "DEVICE_LOCALE_PLACEHOLDER" - sender.data.tags['ai.device.osVersion'] = "DEVICE_OS_VERSION_PLACEHOLDER" - sender.data.tags['ai.device.type'] = "DEVICE_TYPE_PLACEHOLDER" - actual = json.dumps(sender.data.write()) - self.maxDiff = None - self.assertEqual(expected, actual) - - def test_track_exception_works_as_expected(self): - sender = MockTelemetrySender() - queue = channel.SynchronousQueue(sender) - client = TelemetryClient('99999999-9999-9999-9999-999999999999', channel.TelemetryChannel(context=None, queue=queue)) - client.context.device = None - try: - raise Exception("blah") - except Exception as e: - client.track_exception(*sys.exc_info(), properties={}, measurements={ 'x': 42 }) - client.flush() - expected = '{"ver": 1, "name": "Microsoft.ApplicationInsights.Exception", "time": "TIME_PLACEHOLDER", "sampleRate": 100.0, "iKey": "99999999-9999-9999-9999-999999999999", "tags": {"ai.device.id": "DEVICE_ID_PLACEHOLDER", "ai.device.locale": "DEVICE_LOCALE_PLACEHOLDER", "ai.device.osVersion": "DEVICE_OS_VERSION_PLACEHOLDER", "ai.device.type": "DEVICE_TYPE_PLACEHOLDER", "ai.internal.sdkVersion": "SDK_VERSION_PLACEHOLDER"}, "data": {"baseType": "ExceptionData", "baseData": {"ver": 2, "exceptions": [{"id": 1, "outerId": 0, "typeName": "Exception", "message": "blah", "hasFullStack": true, "parsedStack": [{"level": 0, "method": "test_track_exception_works_as_expected", "assembly": "Unknown", "fileName": "TestTelemetryClient.py", "line": 0}]}], "measurements": {"x": 42}}}}' - sender.data.time = 'TIME_PLACEHOLDER' - sender.data.tags['ai.internal.sdkVersion'] = 'SDK_VERSION_PLACEHOLDER' - sender.data.tags['ai.device.id'] = "DEVICE_ID_PLACEHOLDER" - sender.data.tags['ai.device.locale'] = "DEVICE_LOCALE_PLACEHOLDER" - sender.data.tags['ai.device.osVersion'] = "DEVICE_OS_VERSION_PLACEHOLDER" - sender.data.tags['ai.device.type'] = "DEVICE_TYPE_PLACEHOLDER" - for item in sender.data.data.base_data.exceptions: - for frame in item.parsed_stack: - frame.file_name = os.path.basename(frame.file_name) - frame.line = 0 - actual = json.dumps(sender.data.write()) - self.assertEqual(expected, actual) - try: - raise Exception("blah") - except Exception as e: - client.track_exception() - client.flush() - expected = '{"ver": 1, "name": "Microsoft.ApplicationInsights.Exception", "time": "TIME_PLACEHOLDER", "sampleRate": 100.0, "iKey": "99999999-9999-9999-9999-999999999999", "tags": {"ai.device.id": "DEVICE_ID_PLACEHOLDER", "ai.device.locale": "DEVICE_LOCALE_PLACEHOLDER", "ai.device.osVersion": "DEVICE_OS_VERSION_PLACEHOLDER", "ai.device.type": "DEVICE_TYPE_PLACEHOLDER", "ai.internal.sdkVersion": "SDK_VERSION_PLACEHOLDER"}, "data": {"baseType": "ExceptionData", "baseData": {"ver": 2, "exceptions": [{"id": 1, "outerId": 0, "typeName": "Exception", "message": "blah", "hasFullStack": true, "parsedStack": [{"level": 0, "method": "test_track_exception_works_as_expected", "assembly": "Unknown", "fileName": "TestTelemetryClient.py", "line": 0}]}]}}}' - sender.data.time = 'TIME_PLACEHOLDER' - sender.data.tags['ai.internal.sdkVersion'] = 'SDK_VERSION_PLACEHOLDER' - sender.data.tags['ai.device.id'] = "DEVICE_ID_PLACEHOLDER" - sender.data.tags['ai.device.locale'] = "DEVICE_LOCALE_PLACEHOLDER" - sender.data.tags['ai.device.osVersion'] = "DEVICE_OS_VERSION_PLACEHOLDER" - sender.data.tags['ai.device.type'] = "DEVICE_TYPE_PLACEHOLDER" - for item in sender.data.data.base_data.exceptions: - for frame in item.parsed_stack: - frame.file_name = os.path.basename(frame.file_name) - frame.line = 0 - actual = json.dumps(sender.data.write()) - self.assertEqual(expected, actual) - - def test_track_request_works_as_expected(self): - sender = MockTelemetrySender() - queue = channel.SynchronousQueue(sender) - client = TelemetryClient(channel.TelemetryChannel(context=None, queue=queue)) - client.context.instrumentation_key = '99999999-9999-9999-9999-999999999999' - client.context.device = None - client.track_request('test', 'http://tempuri.org', True, 'START_TIME', 13, 42, 'OPTIONS', { 'foo': 'bar' }, { 'x': 42 }, 'ID_PLACEHOLDER') - client.flush() - expected = '{"ver": 1, "name": "Microsoft.ApplicationInsights.Request", "time": "TIME_PLACEHOLDER", "sampleRate": 100.0, "iKey": "99999999-9999-9999-9999-999999999999", "tags": {"ai.device.id": "DEVICE_ID_PLACEHOLDER", "ai.device.locale": "DEVICE_LOCALE_PLACEHOLDER", "ai.device.osVersion": "DEVICE_OS_VERSION_PLACEHOLDER", "ai.device.type": "DEVICE_TYPE_PLACEHOLDER", "ai.internal.sdkVersion": "SDK_VERSION_PLACEHOLDER"}, "data": {"baseType": "RequestData", "baseData": {"ver": 2, "id": "ID_PLACEHOLDER", "name": "test", "duration": "00:00:00.013", "responseCode": "42", "success": true, "url": "http://tempuri.org", "properties": {"foo": "bar"}, "measurements": {"x": 42}}}}' - sender.data.time = 'TIME_PLACEHOLDER' - sender.data.tags['ai.internal.sdkVersion'] = 'SDK_VERSION_PLACEHOLDER' - sender.data.tags['ai.device.id'] = "DEVICE_ID_PLACEHOLDER" - sender.data.tags['ai.device.locale'] = "DEVICE_LOCALE_PLACEHOLDER" - sender.data.tags['ai.device.osVersion'] = "DEVICE_OS_VERSION_PLACEHOLDER" - sender.data.tags['ai.device.type'] = "DEVICE_TYPE_PLACEHOLDER" - actual = json.dumps(sender.data.write()) - self.maxDiff = None - self.assertEqual(expected, actual) - - def test_track_dependency_works_as_expected(self): - sender = MockTelemetrySender() - queue = channel.SynchronousQueue(sender) - client = TelemetryClient(channel.TelemetryChannel(context=None, queue=queue)) - client.context.instrumentation_key = '99999999-9999-9999-9999-999999999999' - client.context.device = None - client.track_dependency('test', 'COMMAND_PLACEHOLDER', 'HTTP', 'localhost', 13, True, 200, { 'foo': 'bar' }, { 'x': 42 }, 'ID_PLACEHOLDER') - client.flush() - expected = '{"ver": 1, "name": "Microsoft.ApplicationInsights.RemoteDependency", "time": "TIME_PLACEHOLDER", "sampleRate": 100.0, "iKey": "99999999-9999-9999-9999-999999999999", "tags": {"ai.device.id": "DEVICE_ID_PLACEHOLDER", "ai.device.locale": "DEVICE_LOCALE_PLACEHOLDER", "ai.device.osVersion": "DEVICE_OS_VERSION_PLACEHOLDER", "ai.device.type": "DEVICE_TYPE_PLACEHOLDER", "ai.internal.sdkVersion": "SDK_VERSION_PLACEHOLDER"}, "data": {"baseType": "RemoteDependencyData", "baseData": {"ver": 2, "name": "test", "id": "ID_PLACEHOLDER", "resultCode": "200", "duration": "00:00:00.013", "success": true, "data": "COMMAND_PLACEHOLDER", "target": "localhost", "type": "HTTP", "properties": {"foo": "bar"}, "measurements": {"x": 42}}}}' - sender.data.time = 'TIME_PLACEHOLDER' - sender.data.tags['ai.internal.sdkVersion'] = 'SDK_VERSION_PLACEHOLDER' - sender.data.tags['ai.device.id'] = "DEVICE_ID_PLACEHOLDER" - sender.data.tags['ai.device.locale'] = "DEVICE_LOCALE_PLACEHOLDER" - sender.data.tags['ai.device.osVersion'] = "DEVICE_OS_VERSION_PLACEHOLDER" - sender.data.tags['ai.device.type'] = "DEVICE_TYPE_PLACEHOLDER" - actual = json.dumps(sender.data.write()) - self.maxDiff = None - self.assertEqual(expected, actual) - - -class MockTelemetrySender(channel.TelemetryChannel().sender.__class__): - def __init__(self): - self.data = None - self.send_buffer_size = 1 - - def send(self, envelope): - self.data = envelope[0] diff --git a/tests/applicationinsights_tests/TestTelemetryProcessor.py b/tests/applicationinsights_tests/TestTelemetryProcessor.py deleted file mode 100644 index cc376bc2..00000000 --- a/tests/applicationinsights_tests/TestTelemetryProcessor.py +++ /dev/null @@ -1,330 +0,0 @@ -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. - -import unittest -import inspect -import json -import sys - -if sys.version_info < (3,0): - from test import test_support -else: - from test import support as test_support - -import os, os.path -rootDirectory = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', '..') -if rootDirectory not in sys.path: - sys.path.append(rootDirectory) - -from applicationinsights import TelemetryClient, channel - - -class TestTelemetryProcessor(unittest.TestCase): - def test_add_null_telemetry_processor(self): - client = TelemetryClient('foo') - self.assertRaises(TypeError, lambda:client.add_telemetry_processor(None)) - - - def test_track_event_processor_filtered(self): - def process(data, context): - return False # Filter the event - - sender = MockTelemetrySender() - queue = channel.SynchronousQueue(sender) - client = TelemetryClient('99999999-9999-9999-9999-999999999999', channel.TelemetryChannel(context=None, queue=queue)) - client.add_telemetry_processor(process) - client.context.device = None - client.track_event('test', { 'foo': 'bar' }, { 'x': 42 }) - client.flush() - self.assertEqual(None, sender.data) - - def test_track_event_modifes_options(self): - def process(data, context): - context.user.id = "BOTUSER" - context.session.id = "BOTSESSION" - return True - - sender = MockTelemetrySender() - queue = channel.SynchronousQueue(sender) - client = TelemetryClient('99999999-9999-9999-9999-999999999999', channel.TelemetryChannel(context=None, queue=queue)) - client.add_telemetry_processor(process) - client.context.device = None - client.context.properties['foo'] = 'bar' - client.track_event('test') - client.flush() - expected = '{"ver": 1, "name": "Microsoft.ApplicationInsights.Event", "time": "TIME_PLACEHOLDER", "sampleRate": 100.0, "iKey": "99999999-9999-9999-9999-999999999999", "tags": {"ai.device.id": "DEVICE_ID_PLACEHOLDER", "ai.device.locale": "DEVICE_LOCALE_PLACEHOLDER", "ai.device.osVersion": "DEVICE_OS_VERSION_PLACEHOLDER", "ai.device.type": "DEVICE_TYPE_PLACEHOLDER", "ai.internal.sdkVersion": "SDK_VERSION_PLACEHOLDER", "ai.session.id": "BOTSESSION", "ai.user.id": "BOTUSER"}, "data": {"baseType": "EventData", "baseData": {"ver": 2, "name": "test", "properties": {"foo": "bar"}}}}' - sender.data.time = 'TIME_PLACEHOLDER' - sender.data.tags['ai.internal.sdkVersion'] = 'SDK_VERSION_PLACEHOLDER' - sender.data.tags['ai.device.id'] = "DEVICE_ID_PLACEHOLDER" - sender.data.tags['ai.device.locale'] = "DEVICE_LOCALE_PLACEHOLDER" - sender.data.tags['ai.device.osVersion'] = "DEVICE_OS_VERSION_PLACEHOLDER" - sender.data.tags['ai.device.type'] = "DEVICE_TYPE_PLACEHOLDER" - actual = json.dumps(sender.data.write()) - self.maxDiff = None - self.assertEqual(expected, actual) - - def test_track_event_with_common_processor_two_clients(self): - def process(data, context): - data.properties["NEW_PROP"] = "MYPROP" - context.user.id = "BOTUSER" - context.session.id = "BOTSESSION" - return True - - key = '99999999-9999-9999-9999-999999999999' - sender = MockTelemetrySender() - queue = channel.SynchronousQueue(sender) - - chan = channel.TelemetryChannel(queue=queue) - chan.context.properties['foo'] = 'bar' - - client1 = TelemetryClient(key, chan) - client1.add_telemetry_processor(process) - client1.context.device = None - client1.context.properties['x'] = 42 - - client2 = TelemetryClient(key, chan) - client2.add_telemetry_processor(process) - client2.context.device = None - client2.context.properties['x'] = 84 - - client1.track_event('test 1') - client1.flush() - sender.data.time = 'TIME_PLACEHOLDER' - sender.data.tags['ai.internal.sdkVersion'] = 'SDK_VERSION_PLACEHOLDER' - sender.data.tags['ai.device.id'] = "DEVICE_ID_PLACEHOLDER" - sender.data.tags['ai.device.locale'] = "DEVICE_LOCALE_PLACEHOLDER" - sender.data.tags['ai.device.osVersion'] = "DEVICE_OS_VERSION_PLACEHOLDER" - sender.data.tags['ai.device.type'] = "DEVICE_TYPE_PLACEHOLDER" - actual = json.dumps(sender.data.write()) - expected = '{"ver": 1, "name": "Microsoft.ApplicationInsights.Event", "time": "TIME_PLACEHOLDER", "sampleRate": 100.0, "iKey": "99999999-9999-9999-9999-999999999999", "tags": {"ai.device.id": "DEVICE_ID_PLACEHOLDER", "ai.device.locale": "DEVICE_LOCALE_PLACEHOLDER", "ai.device.osVersion": "DEVICE_OS_VERSION_PLACEHOLDER", "ai.device.type": "DEVICE_TYPE_PLACEHOLDER", "ai.internal.sdkVersion": "SDK_VERSION_PLACEHOLDER", "ai.session.id": "BOTSESSION", "ai.user.id": "BOTUSER"}, "data": {"baseType": "EventData", "baseData": {"ver": 2, "name": "test 1", "properties": {"NEW_PROP": "MYPROP", "foo": "bar", "x": 42}}}}' - self.maxDiff = None - self.assertEqual(expected, actual) - - client2.track_event('test 2') - client2.flush() - sender.data.time = 'TIME_PLACEHOLDER' - sender.data.tags['ai.internal.sdkVersion'] = 'SDK_VERSION_PLACEHOLDER' - sender.data.tags['ai.device.id'] = "DEVICE_ID_PLACEHOLDER" - sender.data.tags['ai.device.locale'] = "DEVICE_LOCALE_PLACEHOLDER" - sender.data.tags['ai.device.osVersion'] = "DEVICE_OS_VERSION_PLACEHOLDER" - sender.data.tags['ai.device.type'] = "DEVICE_TYPE_PLACEHOLDER" - actual = json.dumps(sender.data.write()) - expected = '{"ver": 1, "name": "Microsoft.ApplicationInsights.Event", "time": "TIME_PLACEHOLDER", "sampleRate": 100.0, "iKey": "99999999-9999-9999-9999-999999999999", "tags": {"ai.device.id": "DEVICE_ID_PLACEHOLDER", "ai.device.locale": "DEVICE_LOCALE_PLACEHOLDER", "ai.device.osVersion": "DEVICE_OS_VERSION_PLACEHOLDER", "ai.device.type": "DEVICE_TYPE_PLACEHOLDER", "ai.internal.sdkVersion": "SDK_VERSION_PLACEHOLDER", "ai.session.id": "BOTSESSION", "ai.user.id": "BOTUSER"}, "data": {"baseType": "EventData", "baseData": {"ver": 2, "name": "test 2", "properties": {"NEW_PROP": "MYPROP", "foo": "bar", "x": 84}}}}' - self.assertEqual(expected, actual) - - def test_track_event_processor_modifies_data(self): - def process(data, context): - data.name = "WOWTESTING" - data.ver = 30000 - return True - - sender = MockTelemetrySender() - queue = channel.SynchronousQueue(sender) - client = TelemetryClient('99999999-9999-9999-9999-999999999999', channel.TelemetryChannel(context=None, queue=queue)) - client.add_telemetry_processor(process) - client.context.device = None - client.track_event('test', { 'foo': 'bar' }, { 'x': 42 }) - client.flush() - expected = '{"ver": 1, "name": "Microsoft.ApplicationInsights.Event", "time": "TIME_PLACEHOLDER", "sampleRate": 100.0, "iKey": "99999999-9999-9999-9999-999999999999", "tags": {"ai.device.id": "DEVICE_ID_PLACEHOLDER", "ai.device.locale": "DEVICE_LOCALE_PLACEHOLDER", "ai.device.osVersion": "DEVICE_OS_VERSION_PLACEHOLDER", "ai.device.type": "DEVICE_TYPE_PLACEHOLDER", "ai.internal.sdkVersion": "SDK_VERSION_PLACEHOLDER"}, "data": {"baseType": "EventData", "baseData": {"ver": 30000, "name": "WOWTESTING", "properties": {"foo": "bar"}, "measurements": {"x": 42}}}}' - sender.data.time = 'TIME_PLACEHOLDER' - sender.data.tags['ai.internal.sdkVersion'] = 'SDK_VERSION_PLACEHOLDER' - sender.data.tags['ai.device.id'] = "DEVICE_ID_PLACEHOLDER" - sender.data.tags['ai.device.locale'] = "DEVICE_LOCALE_PLACEHOLDER" - sender.data.tags['ai.device.osVersion'] = "DEVICE_OS_VERSION_PLACEHOLDER" - sender.data.tags['ai.device.type'] = "DEVICE_TYPE_PLACEHOLDER" - actual = json.dumps(sender.data.write()) - self.maxDiff = None - self.assertEqual(expected, actual) - - def test_track_metric_works_as_expected(self): - def process(data, context): - data.properties["NEW_PROP"] = "MYPROP" - context.user.id = "BOTUSER" - context.session.id = "BOTSESSION" - return True - sender = MockTelemetrySender() - queue = channel.SynchronousQueue(sender) - client = TelemetryClient('99999999-9999-9999-9999-999999999999', channel.TelemetryChannel(context=None, queue=queue)) - client.add_telemetry_processor(process) - client.context.device = None - client.track_metric('metric', 42, channel.contracts.DataPointType.aggregation, 13, 1, 123, 111, {'foo': 'bar'}) - client.flush() - expected = '{"ver": 1, "name": "Microsoft.ApplicationInsights.Metric", "time": "TIME_PLACEHOLDER", "sampleRate": 100.0, "iKey": "99999999-9999-9999-9999-999999999999", "tags": {"ai.device.id": "DEVICE_ID_PLACEHOLDER", "ai.device.locale": "DEVICE_LOCALE_PLACEHOLDER", "ai.device.osVersion": "DEVICE_OS_VERSION_PLACEHOLDER", "ai.device.type": "DEVICE_TYPE_PLACEHOLDER", "ai.internal.sdkVersion": "SDK_VERSION_PLACEHOLDER", "ai.session.id": "BOTSESSION", "ai.user.id": "BOTUSER"}, "data": {"baseType": "MetricData", "baseData": {"ver": 2, "metrics": [{"name": "metric", "kind": 1, "value": 42, "count": 13, "min": 1, "max": 123, "stdDev": 111}], "properties": {"NEW_PROP": "MYPROP", "foo": "bar"}}}}' - sender.data.time = 'TIME_PLACEHOLDER' - sender.data.tags['ai.internal.sdkVersion'] = 'SDK_VERSION_PLACEHOLDER' - sender.data.tags['ai.device.id'] = "DEVICE_ID_PLACEHOLDER" - sender.data.tags['ai.device.locale'] = "DEVICE_LOCALE_PLACEHOLDER" - sender.data.tags['ai.device.osVersion'] = "DEVICE_OS_VERSION_PLACEHOLDER" - sender.data.tags['ai.device.type'] = "DEVICE_TYPE_PLACEHOLDER" - actual = json.dumps(sender.data.write()) - self.maxDiff = None - self.assertEqual(expected, actual) - - def test_track_trace_works_as_expected(self): - def process(data, context): - data.properties["NEW_PROP"] = "MYPROP" - context.user.id = "BOTUSER" - context.session.id = "BOTSESSION" - return True - - sender = MockTelemetrySender() - queue = channel.SynchronousQueue(sender) - client = TelemetryClient('99999999-9999-9999-9999-999999999999', channel.TelemetryChannel(context=None, queue=queue)) - client.add_telemetry_processor(process) - client.context.device = None - client.track_trace('test', { 'foo': 'bar' }, severity='WARNING') - client.flush() - expected = '{"ver": 1, "name": "Microsoft.ApplicationInsights.Message", "time": "TIME_PLACEHOLDER", "sampleRate": 100.0, "iKey": "99999999-9999-9999-9999-999999999999", "tags": {"ai.device.id": "DEVICE_ID_PLACEHOLDER", "ai.device.locale": "DEVICE_LOCALE_PLACEHOLDER", "ai.device.osVersion": "DEVICE_OS_VERSION_PLACEHOLDER", "ai.device.type": "DEVICE_TYPE_PLACEHOLDER", "ai.internal.sdkVersion": "SDK_VERSION_PLACEHOLDER", "ai.session.id": "BOTSESSION", "ai.user.id": "BOTUSER"}, "data": {"baseType": "MessageData", "baseData": {"ver": 2, "message": "test", "severityLevel": 2, "properties": {"NEW_PROP": "MYPROP", "foo": "bar"}}}}' - sender.data.time = 'TIME_PLACEHOLDER' - sender.data.tags['ai.internal.sdkVersion'] = 'SDK_VERSION_PLACEHOLDER' - sender.data.tags['ai.device.id'] = "DEVICE_ID_PLACEHOLDER" - sender.data.tags['ai.device.locale'] = "DEVICE_LOCALE_PLACEHOLDER" - sender.data.tags['ai.device.osVersion'] = "DEVICE_OS_VERSION_PLACEHOLDER" - sender.data.tags['ai.device.type'] = "DEVICE_TYPE_PLACEHOLDER" - actual = json.dumps(sender.data.write()) - self.maxDiff = None - self.assertEqual(expected, actual) - - def test_track_pageview_works_as_expected(self): - def process(data, context): - data.properties["NEW_PROP"] = "MYPROP" - context.user.id = "BOTUSER" - context.session.id = "BOTSESSION" - return True - - sender = MockTelemetrySender() - queue = channel.SynchronousQueue(sender) - client = TelemetryClient('99999999-9999-9999-9999-999999999999', channel.TelemetryChannel(context=None, queue=queue)) - client.add_telemetry_processor(process) - client.context.device = None - client.track_pageview('test', 'http://tempuri.org', 13, { 'foo': 'bar' }, { 'x': 42 }) - client.flush() - expected = '{"ver": 1, "name": "Microsoft.ApplicationInsights.PageView", "time": "TIME_PLACEHOLDER", "sampleRate": 100.0, "iKey": "99999999-9999-9999-9999-999999999999", "tags": {"ai.device.id": "DEVICE_ID_PLACEHOLDER", "ai.device.locale": "DEVICE_LOCALE_PLACEHOLDER", "ai.device.osVersion": "DEVICE_OS_VERSION_PLACEHOLDER", "ai.device.type": "DEVICE_TYPE_PLACEHOLDER", "ai.internal.sdkVersion": "SDK_VERSION_PLACEHOLDER", "ai.session.id": "BOTSESSION", "ai.user.id": "BOTUSER"}, "data": {"baseType": "PageViewData", "baseData": {"ver": 2, "url": "http://tempuri.org", "name": "test", "duration": 13, "properties": {"NEW_PROP": "MYPROP", "foo": "bar"}, "measurements": {"x": 42}}}}' - sender.data.time = 'TIME_PLACEHOLDER' - sender.data.tags['ai.internal.sdkVersion'] = 'SDK_VERSION_PLACEHOLDER' - sender.data.tags['ai.device.id'] = "DEVICE_ID_PLACEHOLDER" - sender.data.tags['ai.device.locale'] = "DEVICE_LOCALE_PLACEHOLDER" - sender.data.tags['ai.device.osVersion'] = "DEVICE_OS_VERSION_PLACEHOLDER" - sender.data.tags['ai.device.type'] = "DEVICE_TYPE_PLACEHOLDER" - actual = json.dumps(sender.data.write()) - self.maxDiff = None - self.assertEqual(expected, actual) - - def test_track_exception_works_as_expected(self): - def process(data, context): - data.properties["NEW_PROP"] = "MYPROP" - context.user.id = "BOTUSER" - context.session.id = "BOTSESSION" - return True - - sender = MockTelemetrySender() - queue = channel.SynchronousQueue(sender) - client = TelemetryClient('99999999-9999-9999-9999-999999999999', channel.TelemetryChannel(context=None, queue=queue)) - client.add_telemetry_processor(process) - client.context.device = None - try: - raise Exception("blah") - except Exception as e: - client.track_exception(*sys.exc_info(), properties={}, measurements={ 'x': 42 }) - client.flush() - expected = '{"ver": 1, "name": "Microsoft.ApplicationInsights.Exception", "time": "TIME_PLACEHOLDER", "sampleRate": 100.0, "iKey": "99999999-9999-9999-9999-999999999999", "tags": {"ai.device.id": "DEVICE_ID_PLACEHOLDER", "ai.device.locale": "DEVICE_LOCALE_PLACEHOLDER", "ai.device.osVersion": "DEVICE_OS_VERSION_PLACEHOLDER", "ai.device.type": "DEVICE_TYPE_PLACEHOLDER", "ai.internal.sdkVersion": "SDK_VERSION_PLACEHOLDER", "ai.session.id": "BOTSESSION", "ai.user.id": "BOTUSER"}, "data": {"baseType": "ExceptionData", "baseData": {"ver": 2, "exceptions": [{"id": 1, "outerId": 0, "typeName": "Exception", "message": "blah", "hasFullStack": true, "parsedStack": [{"level": 0, "method": "test_track_exception_works_as_expected", "assembly": "Unknown", "fileName": "TestTelemetryProcessor.py", "line": 0}]}], "properties": {"NEW_PROP": "MYPROP"}, "measurements": {"x": 42}}}}' - sender.data.time = 'TIME_PLACEHOLDER' - sender.data.tags['ai.internal.sdkVersion'] = 'SDK_VERSION_PLACEHOLDER' - sender.data.tags['ai.device.id'] = "DEVICE_ID_PLACEHOLDER" - sender.data.tags['ai.device.locale'] = "DEVICE_LOCALE_PLACEHOLDER" - sender.data.tags['ai.device.osVersion'] = "DEVICE_OS_VERSION_PLACEHOLDER" - sender.data.tags['ai.device.type'] = "DEVICE_TYPE_PLACEHOLDER" - for item in sender.data.data.base_data.exceptions: - for frame in item.parsed_stack: - frame.file_name = os.path.basename(frame.file_name) - frame.line = 0 - actual = json.dumps(sender.data.write()) - self.maxDiff = None - self.assertEqual(expected, actual) - try: - raise Exception("blah") - except Exception as e: - client.track_exception() - client.flush() - expected = '{"ver": 1, "name": "Microsoft.ApplicationInsights.Exception", "time": "TIME_PLACEHOLDER", "sampleRate": 100.0, "iKey": "99999999-9999-9999-9999-999999999999", "tags": {"ai.device.id": "DEVICE_ID_PLACEHOLDER", "ai.device.locale": "DEVICE_LOCALE_PLACEHOLDER", "ai.device.osVersion": "DEVICE_OS_VERSION_PLACEHOLDER", "ai.device.type": "DEVICE_TYPE_PLACEHOLDER", "ai.internal.sdkVersion": "SDK_VERSION_PLACEHOLDER", "ai.session.id": "BOTSESSION", "ai.user.id": "BOTUSER"}, "data": {"baseType": "ExceptionData", "baseData": {"ver": 2, "exceptions": [{"id": 1, "outerId": 0, "typeName": "Exception", "message": "blah", "hasFullStack": true, "parsedStack": [{"level": 0, "method": "test_track_exception_works_as_expected", "assembly": "Unknown", "fileName": "TestTelemetryProcessor.py", "line": 0}]}], "properties": {"NEW_PROP": "MYPROP"}}}}' - sender.data.time = 'TIME_PLACEHOLDER' - sender.data.tags['ai.internal.sdkVersion'] = 'SDK_VERSION_PLACEHOLDER' - sender.data.tags['ai.device.id'] = "DEVICE_ID_PLACEHOLDER" - sender.data.tags['ai.device.locale'] = "DEVICE_LOCALE_PLACEHOLDER" - sender.data.tags['ai.device.osVersion'] = "DEVICE_OS_VERSION_PLACEHOLDER" - sender.data.tags['ai.device.type'] = "DEVICE_TYPE_PLACEHOLDER" - for item in sender.data.data.base_data.exceptions: - for frame in item.parsed_stack: - frame.file_name = os.path.basename(frame.file_name) - frame.line = 0 - actual = json.dumps(sender.data.write()) - self.assertEqual(expected, actual) - - def test_track_request_works_as_expected(self): - def process(data, context): - data.properties["NEW_PROP"] = "MYPROP" - context.user.id = "BOTUSER" - context.session.id = "BOTSESSION" - return True - - sender = MockTelemetrySender() - queue = channel.SynchronousQueue(sender) - client = TelemetryClient(channel.TelemetryChannel(context=None, queue=queue)) - client.add_telemetry_processor(process) - client.context.instrumentation_key = '99999999-9999-9999-9999-999999999999' - client.context.device = None - client.track_request('test', 'http://tempuri.org', True, 'START_TIME', 13, 42, 'OPTIONS', { 'foo': 'bar' }, { 'x': 42 }, 'ID_PLACEHOLDER') - client.flush() - expected = '{"ver": 1, "name": "Microsoft.ApplicationInsights.Request", "time": "TIME_PLACEHOLDER", "sampleRate": 100.0, "iKey": "99999999-9999-9999-9999-999999999999", "tags": {"ai.device.id": "DEVICE_ID_PLACEHOLDER", "ai.device.locale": "DEVICE_LOCALE_PLACEHOLDER", "ai.device.osVersion": "DEVICE_OS_VERSION_PLACEHOLDER", "ai.device.type": "DEVICE_TYPE_PLACEHOLDER", "ai.internal.sdkVersion": "SDK_VERSION_PLACEHOLDER", "ai.session.id": "BOTSESSION", "ai.user.id": "BOTUSER"}, "data": {"baseType": "RequestData", "baseData": {"ver": 2, "id": "ID_PLACEHOLDER", "name": "test", "duration": "00:00:00.013", "responseCode": "42", "success": true, "url": "http://tempuri.org", "properties": {"NEW_PROP": "MYPROP", "foo": "bar"}, "measurements": {"x": 42}}}}' - sender.data.time = 'TIME_PLACEHOLDER' - sender.data.tags['ai.internal.sdkVersion'] = 'SDK_VERSION_PLACEHOLDER' - sender.data.tags['ai.device.id'] = "DEVICE_ID_PLACEHOLDER" - sender.data.tags['ai.device.locale'] = "DEVICE_LOCALE_PLACEHOLDER" - sender.data.tags['ai.device.osVersion'] = "DEVICE_OS_VERSION_PLACEHOLDER" - sender.data.tags['ai.device.type'] = "DEVICE_TYPE_PLACEHOLDER" - actual = json.dumps(sender.data.write()) - self.maxDiff = None - self.assertEqual(expected, actual) - - def test_track_dependency_works_as_expected(self): - def process(data, context): - data.properties["NEW_PROP"] = "MYPROP" - context.user.id = "BOTUSER" - context.session.id = "BOTSESSION" - return True - - sender = MockTelemetrySender() - queue = channel.SynchronousQueue(sender) - client = TelemetryClient(channel.TelemetryChannel(context=None, queue=queue)) - client.add_telemetry_processor(process) - client.context.instrumentation_key = '99999999-9999-9999-9999-999999999999' - client.context.device = None - client.track_dependency('test', 'COMMAND_PLACEHOLDER', 'HTTP', 'localhost', 13, True, 200, { 'foo': 'bar' }, { 'x': 42 }, 'ID_PLACEHOLDER') - client.flush() - expected = '{"ver": 1, "name": "Microsoft.ApplicationInsights.RemoteDependency", "time": "TIME_PLACEHOLDER", "sampleRate": 100.0, "iKey": "99999999-9999-9999-9999-999999999999", "tags": {"ai.device.id": "DEVICE_ID_PLACEHOLDER", "ai.device.locale": "DEVICE_LOCALE_PLACEHOLDER", "ai.device.osVersion": "DEVICE_OS_VERSION_PLACEHOLDER", "ai.device.type": "DEVICE_TYPE_PLACEHOLDER", "ai.internal.sdkVersion": "SDK_VERSION_PLACEHOLDER", "ai.session.id": "BOTSESSION", "ai.user.id": "BOTUSER"}, "data": {"baseType": "RemoteDependencyData", "baseData": {"ver": 2, "name": "test", "id": "ID_PLACEHOLDER", "resultCode": "200", "duration": "00:00:00.013", "success": true, "data": "COMMAND_PLACEHOLDER", "target": "localhost", "type": "HTTP", "properties": {"NEW_PROP": "MYPROP", "foo": "bar"}, "measurements": {"x": 42}}}}' - sender.data.time = 'TIME_PLACEHOLDER' - sender.data.tags['ai.internal.sdkVersion'] = 'SDK_VERSION_PLACEHOLDER' - sender.data.tags['ai.device.id'] = "DEVICE_ID_PLACEHOLDER" - sender.data.tags['ai.device.locale'] = "DEVICE_LOCALE_PLACEHOLDER" - sender.data.tags['ai.device.osVersion'] = "DEVICE_OS_VERSION_PLACEHOLDER" - sender.data.tags['ai.device.type'] = "DEVICE_TYPE_PLACEHOLDER" - actual = json.dumps(sender.data.write()) - self.maxDiff = None - self.assertEqual(expected, actual) - - def test_constructor_throws_with_no_instrumentation_key(self): - self.assertRaises(Exception, TelemetryClient, None) - -class MockTelemetryProcessor(): - def process(data, options): - print(str(data)) - print(str(options)) - - -class MockTelemetrySender(channel.TelemetryChannel().sender.__class__): - def __init__(self): - self.data = None - self.send_buffer_size = 1 - - def send(self, envelope): - self.data = envelope[0] diff --git a/tests/applicationinsights_tests/__init__.py b/tests/applicationinsights_tests/__init__.py deleted file mode 100644 index 3bc5f578..00000000 --- a/tests/applicationinsights_tests/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -from . import TestTelemetryClient -from . import channel_tests -from . import exception_tests -from . import logging_tests -from . import requests_tests \ No newline at end of file diff --git a/tests/applicationinsights_tests/channel_tests/TestAsynchronousQueue.py b/tests/applicationinsights_tests/channel_tests/TestAsynchronousQueue.py deleted file mode 100644 index fe392dde..00000000 --- a/tests/applicationinsights_tests/channel_tests/TestAsynchronousQueue.py +++ /dev/null @@ -1,65 +0,0 @@ -import unittest - -import sys, os, os.path -rootDirectory = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', '..') -if rootDirectory not in sys.path: - sys.path.append(rootDirectory) - -from applicationinsights import channel - -class TestAsynchronousQueue(unittest.TestCase): - def test_construct(self): - queue = channel.AsynchronousQueue(MockAsynchronousSender()) - self.assertIsNotNone(queue.flush_notification) - - def test_flush_notification_works_as_expected(self): - queue = channel.AsynchronousQueue(MockAsynchronousSender()) - self.assertIsNotNone(queue.flush_notification) - result = queue.flush_notification.wait(1) - self.assertEqual(False, result) - queue.flush_notification.set() - result = queue.flush_notification.wait() - self.assertEqual(True, result) - queue.flush_notification.clear() - result = queue.flush_notification.wait(1) - self.assertEqual(False, result) - - def test_push_works_As_expected(self): - sender = MockAsynchronousSender() - queue = channel.AsynchronousQueue(sender) - queue.put(42) - self.assertEqual(1, sender.start_call_count) - self.assertEqual(42, queue.get()) - self.assertIsNone(queue.get()) - - def test_flush_works_as_expected(self): - sender = MockAsynchronousSender() - queue = channel.AsynchronousQueue(sender) - self.assertIsNotNone(queue.flush_notification) - result = queue.flush_notification.wait(1) - self.assertEqual(False, result) - queue.flush() - self.assertEqual(1, sender.start_call_count) - result = queue.flush_notification.wait() - self.assertEqual(True, result) - - def test_with_null_sender(self): - sender = channel.NullSender() - queue = channel.AsynchronousQueue(sender) - queue.put(1) - queue.put(2) - queue.flush() - - -class MockAsynchronousSender: - def __init__(self): - self.send_buffer_size = 2 - self.data = [] - self.queue = None - self.start_call_count = 0 - - def start(self): - self.start_call_count += 1 - - def send(self, data_to_send): - self.data.append(data_to_send) diff --git a/tests/applicationinsights_tests/channel_tests/TestAsynchronousSender.py b/tests/applicationinsights_tests/channel_tests/TestAsynchronousSender.py deleted file mode 100644 index aeac0ad7..00000000 --- a/tests/applicationinsights_tests/channel_tests/TestAsynchronousSender.py +++ /dev/null @@ -1,73 +0,0 @@ -import unittest -import time - -import sys, os, os.path -rootDirectory = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', '..') -if rootDirectory not in sys.path: - sys.path.append(rootDirectory) - -from applicationinsights import channel - -class TestAsynchronousSender(unittest.TestCase): - def test_construct(self): - sender = channel.AsynchronousSender() - self.assertEqual('https://dc.services.visualstudio.com/v2/track', sender.service_endpoint_uri) - self.assertEqual(1.0, sender.send_interval) - self.assertEqual(3.0, sender.send_time) - - def test_send_interval_works_as_expected(self): - sender = channel.AsynchronousSender() - self.assertEqual(1.0, sender.send_interval) - sender.send_interval = 10.0 - self.assertEqual(10.0, sender.send_interval) - - def test_send_time_works_as_expected(self): - sender = channel.AsynchronousSender() - self.assertEqual(3.0, sender.send_time) - sender.send_time = 10.0 - self.assertEqual(10.0, sender.send_time) - - def test_start(self): - sender = InterceptableAsynchronousSender() - sender.send_interval = 1.0 - sender.send_time = 3.0 - queue = InterceptableAsynchronousQueue(sender) - sender.invoke_base_start = False - queue.put(1) - queue.put(2) - sender.invoke_base_start = True - sender.start() - time.sleep(2.0 * sender.send_time / 3.0) - queue.put(3) - time.sleep((1.0 * sender.send_time / 3.0) + 2.0) - data = sender.data_to_send - if [[1, 2], [3]] != data and [[1, 2]] != data: - self.fail('Invalid result') - get_calls = queue.get_calls - if 10 != len(get_calls) and 6 != len(get_calls): - self.fail('Invalid count') - - -class InterceptableAsynchronousQueue(channel.AsynchronousQueue): - def __init__(self, sender): - self.get_calls = [] - channel.AsynchronousQueue.__init__(self, sender) - - def get(self): - output = channel.AsynchronousQueue.get(self) - self.get_calls.append((time.gmtime(), output)) - return output - - -class InterceptableAsynchronousSender(channel.AsynchronousSender): - def __init__(self): - self.data_to_send = [] - self.invoke_base_start = False - channel.AsynchronousSender.__init__(self) - - def start(self): - if self.invoke_base_start: - channel.AsynchronousSender.start(self) - - def send(self, data_to_send): - self.data_to_send.append(data_to_send) \ No newline at end of file diff --git a/tests/applicationinsights_tests/channel_tests/TestQueueBase.py b/tests/applicationinsights_tests/channel_tests/TestQueueBase.py deleted file mode 100644 index 6ec6bada..00000000 --- a/tests/applicationinsights_tests/channel_tests/TestQueueBase.py +++ /dev/null @@ -1,90 +0,0 @@ -import unittest - -import sys, os, os.path -from shutil import rmtree -from tempfile import mkdtemp - -rootDirectory = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', '..') -if rootDirectory not in sys.path: - sys.path.append(rootDirectory) - -from applicationinsights import channel -from applicationinsights.channel.QueueBase import PersistQueue - -class TestQueueBase(unittest.TestCase): - def test_construct(self): - sender = MockQueueBaseSender() - actual = channel.QueueBase(sender) - self.assertIsNotNone(actual) - self.assertEqual(500, actual.max_queue_length) - self.assertEqual(sender, actual.sender) - self.assertEqual(actual, sender.queue) - - def test_max_queue_length_works_as_expected(self): - actual = channel.QueueBase(None) - self.assertEqual(500, actual.max_queue_length) - actual.max_queue_length = 1000 - self.assertEqual(1000, actual.max_queue_length) - actual.max_queue_length = -1 - self.assertEqual(1, actual.max_queue_length) - - def test_sender_works_as_expected(self): - sender = MockQueueBaseSender() - actual = channel.QueueBase(sender) - self.assertEqual(sender, actual.sender) - - def test_put_works_as_expected(self): - actual = InterceptableQueueBase(None) - actual.max_queue_length = 1 - actual.put(None) - actual.put(1) - actual.put(2) - self.assertEqual(1, actual.get()) - self.assertEqual(2, actual.get()) - self.assertEqual(None, actual.get()) - self.assertEqual(None, actual.get()) - self.assertEqual(2, actual.flush_count) - - def test_get_works_as_expected(self): - self.test_put_works_as_expected() - - def test_flush_works_as_expected(self): - self.test_put_works_as_expected() - - @unittest.skipIf(PersistQueue is None, reason='persist-queue missing') - def test_queue_persistence(self): - queue = channel.QueueBase(None, self.persistence_directory) - queue.put(1) - queue.put(2) - self.assertEqual(1, queue.get()) - queue.put(3) - del queue - queue = channel.QueueBase(None, self.persistence_directory) - queue.put(4) - self.assertEqual(2, queue.get()) - self.assertEqual(3, queue.get()) - self.assertEqual(4, queue.get()) - self.assertEqual(None, queue.get()) - - @unittest.skipIf(PersistQueue is not None, reason='persist-queue exists') - def test_queue_persistence_without_dependency(self): - with self.assertRaises(ValueError): - channel.QueueBase(None, self.persistence_directory) - - def setUp(self): - self.persistence_directory = mkdtemp() - - def tearDown(self): - rmtree(self.persistence_directory) - -class InterceptableQueueBase(channel.QueueBase): - def __init__(self, sender): - channel.QueueBase.__init__(self, sender) - self.flush_count = 0 - - def flush(self): - self.flush_count += 1 - -class MockQueueBaseSender(object): - def __init__(self): - self.queue = None \ No newline at end of file diff --git a/tests/applicationinsights_tests/channel_tests/TestSenderBase.py b/tests/applicationinsights_tests/channel_tests/TestSenderBase.py deleted file mode 100644 index 53efa0fd..00000000 --- a/tests/applicationinsights_tests/channel_tests/TestSenderBase.py +++ /dev/null @@ -1,110 +0,0 @@ -import random -import unittest -import time -import threading - -try: - # Python 2.x - import BaseHTTPServer as HTTPServer -except ImportError: - # Python 3.x - import http.server as HTTPServer - -import sys, os, os.path -rootDirectory = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', '..') -if rootDirectory not in sys.path: - sys.path.append(rootDirectory) - -from applicationinsights import channel - -class TestSenderBase(unittest.TestCase): - def test_construct(self): - actual = channel.SenderBase('http://tempuri.org/') - self.assertIsNotNone(actual) - self.assertEqual('http://tempuri.org/', actual.service_endpoint_uri) - self.assertIsNone(actual.queue) - self.assertEqual(100, actual.send_buffer_size) - - def test_service_endpoint_uri_works_as_expected(self): - actual = channel.SenderBase('http://tempuri.org/') - self.assertEqual('http://tempuri.org/', actual.service_endpoint_uri) - actual.service_endpoint_uri = 'foo' - self.assertEqual('foo', actual.service_endpoint_uri) - - def test_queue_works_as_expected(self): - actual = channel.SenderBase('http://tempuri.org/') - self.assertIsNone(actual.queue) - expected = object() - actual.queue = expected - self.assertEqual(expected, actual.queue) - - def test_send_buffer_size_works_as_expected(self): - actual = channel.SenderBase('http://tempuri.org/') - self.assertEqual(100, actual.send_buffer_size) - actual.send_buffer_size = 42 - self.assertEqual(42, actual.send_buffer_size) - actual.send_buffer_size = -1 - self.assertEqual(1, actual.send_buffer_size) - - def test_send_works_as_expected(self): - port = random.randint(50000, 60000) - actual = channel.SenderBase("http://localhost:" + str(port) + "/track") - actual.queue = channel.QueueBase(None) - MockHTTPRequestHandler.ExpectedContent = "[42, 13]" - MockHTTPRequestHandler.TestCase = self # save a reference to the test case in our handler - thread = WorkerThread(actual) - thread.start() - runHttpHandlerOnce(handler=MockHTTPRequestHandler, port=port) # run the HTTP request - thread.join() - if "failed" in dir(self): - self.fail(self.failed) - self.assertEqual(None, actual.queue.get()) - - -class WorkerThread(threading.Thread): - def __init__(self, sender): - threading.Thread.__init__(self) - self.sender = sender - - def run(self): - time.sleep(1) - self.sender.send([ MockSerializable(42), MockSerializable(13) ]) - - -class MockSerializable(object): - def __init__(self, data): - self._data = data - - def write(self): - return self._data - - -class MockHTTPRequestHandler(HTTPServer.BaseHTTPRequestHandler): - ExpectedContent = None - TestCase = None - def do_POST(self): - contentLength = int(self.headers['Content-Length']) - content = self.rfile.read(contentLength) - response = "" - if isinstance(content, bytes): - content = content.decode("utf-8") - response = b"" - - if "POST" != self.command: - MockHTTPRequestHandler.TestCase.failed = '"POST" != self.command' - if "application/json; charset=utf-8" != self.headers["Content-Type"]: - MockHTTPRequestHandler.TestCase.failed = '"application/json; charset=utf-8" != self.headers.type' - if MockHTTPRequestHandler.ExpectedContent != content: - MockHTTPRequestHandler.TestCase.failed = '"' + MockHTTPRequestHandler.ExpectedContent + '" != content' - - self.send_response(200) - self.send_header("Content-Type", "application/json") - self.send_header("Content-Length", "0") - self.end_headers() - self.wfile.write(response) - - -def runHttpHandlerOnce(server=HTTPServer.HTTPServer, handler=HTTPServer.BaseHTTPRequestHandler, port=8121): - serverAddress = ('', port) - httpd = server(serverAddress, handler) - httpd.handle_request() \ No newline at end of file diff --git a/tests/applicationinsights_tests/channel_tests/TestSynchronousQueue.py b/tests/applicationinsights_tests/channel_tests/TestSynchronousQueue.py deleted file mode 100644 index 9a0aa4d2..00000000 --- a/tests/applicationinsights_tests/channel_tests/TestSynchronousQueue.py +++ /dev/null @@ -1,35 +0,0 @@ -import unittest - -import sys, os, os.path -rootDirectory = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', '..') -if rootDirectory not in sys.path: - sys.path.append(rootDirectory) - -from applicationinsights import channel - -class TestSynchronousQueue(unittest.TestCase): - def test_construct(self): - actual = channel.SynchronousQueue(MockSynchronousSender()) - self.assertIsNotNone(actual) - - def test_flush_works_as_expected(self): - sender = MockSynchronousSender() - queue = channel.SynchronousQueue(sender) - queue.max_queue_length = 3 - for i in range(1, 8): - queue.put(i) - self.assertEqual([[1, 2], [3], [4, 5], [6]], sender.data) - temp = [] - while queue._queue.qsize() > 0: - temp.append(queue._queue.get()) - self.assertEqual([7], temp) - - -class MockSynchronousSender: - def __init__(self): - self.send_buffer_size = 2 - self.data = [] - self.queue = None - - def send(self, data_to_send): - self.data.append(data_to_send) diff --git a/tests/applicationinsights_tests/channel_tests/TestSynchronousSender.py b/tests/applicationinsights_tests/channel_tests/TestSynchronousSender.py deleted file mode 100644 index 5691cdff..00000000 --- a/tests/applicationinsights_tests/channel_tests/TestSynchronousSender.py +++ /dev/null @@ -1,13 +0,0 @@ -import unittest - -import sys, os, os.path -rootDirectory = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', '..') -if rootDirectory not in sys.path: - sys.path.append(rootDirectory) - -from applicationinsights import channel - -class TestSynchronousSender(unittest.TestCase): - def test_construct(self): - sender = channel.SynchronousSender() - self.assertEqual('https://dc.services.visualstudio.com/v2/track', sender.service_endpoint_uri) diff --git a/tests/applicationinsights_tests/channel_tests/TestTelemetryChannel.py b/tests/applicationinsights_tests/channel_tests/TestTelemetryChannel.py deleted file mode 100644 index ad25fffa..00000000 --- a/tests/applicationinsights_tests/channel_tests/TestTelemetryChannel.py +++ /dev/null @@ -1,127 +0,0 @@ -import unittest - -import sys, os, os.path -rootDirectory = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', '..', '..') -if rootDirectory not in sys.path: - sys.path.append(rootDirectory) - -from applicationinsights import channel - -class TestTelemetryChannel(unittest.TestCase): - def test_construct(self): - actual = channel.TelemetryChannel() - self.assertIsNotNone(actual) - - def test_context_works_as_expected(self): - context_global = channel.TelemetryContext() - context_global.device.id = "global" - actual = channel.TelemetryChannel() - self.assertIsNotNone(actual.context) - actual = channel.TelemetryChannel(None) - self.assertIsNotNone(actual.context) - actual = channel.TelemetryChannel(context_global) - self.assertEqual(context_global, actual.context) - - def test_queue_works_as_expected(self): - queue = object() - actual = channel.TelemetryChannel() - self.assertIsNotNone(actual.queue) - actual = channel.TelemetryChannel(None, None) - self.assertIsNotNone(actual.queue) - actual = channel.TelemetryChannel(None, queue) - self.assertEqual(queue, actual.queue) - - def test_sender_works_as_expected(self): - actual = channel.TelemetryChannel() - self.assertIsNotNone(actual.sender) - - def test_flush_works_as_expected(self): - queue = MockQueue() - actual = channel.TelemetryChannel(None, queue) - self.assertEqual(0, queue.flush_count) - actual.flush() - self.assertEqual(1, queue.flush_count) - - def test_construct_with_context_and_sender(self): - mock_sender = MockTelemetrySender() - queue = channel.SynchronousQueue(mock_sender) - context_global = channel.TelemetryContext() - context_global.device.id = "global" - actual = channel.TelemetryChannel(context_global, queue) - actual.write(channel.contracts.MessageData()) - actual.flush() - self.assertIsNotNone(mock_sender.data) - self.assertEqual("global", mock_sender.data.tags["ai.device.id"]) - - def test_write_with_no_data_raises_exception(self): - mock_sender = MockTelemetrySender() - queue = channel.SynchronousQueue(mock_sender) - actual = channel.TelemetryChannel(None, queue) - self.assertRaises(Exception, actual.write, None) - - def test_write_transfers_local_convext_over_global_context(self): - mock_sender = MockTelemetrySender() - queue = channel.SynchronousQueue(mock_sender) - context_global = channel.TelemetryContext() - context_global.device.id = "global" - context_local = channel.TelemetryContext() - context_local.device.id = "local" - actual = channel.TelemetryChannel(context_global, queue) - actual.write(channel.contracts.MessageData(), context_local) - actual.flush() - self.assertIsNotNone(mock_sender.data) - self.assertEqual("local", mock_sender.data.tags["ai.device.id"]) - - def test_write_constructs_valid_envelope(self): - mock_sender = MockTelemetrySender() - queue = channel.SynchronousQueue(mock_sender) - context_global = channel.TelemetryContext() - context_global.instrumentation_key = "42" - actual = channel.TelemetryChannel(context_global, queue) - cases = [ - channel.contracts.EventData(), - channel.contracts.MetricData(), - channel.contracts.MessageData(), - channel.contracts.PageViewData(), - channel.contracts.ExceptionData(), - ] - for item in cases: - actual.write(item) - actual.flush() - self.assertIsNotNone(mock_sender.data) - self.assertTrue(isinstance(mock_sender.data, channel.contracts.Envelope)) - self.assertEqual(item.ENVELOPE_TYPE_NAME, mock_sender.data.name) - self.assertIsNotNone(mock_sender.data.time) - self.assertEqual("42", mock_sender.data.ikey) - for key, value in context_global.device.write().items(): - self.assertEqual(value, mock_sender.data.tags[key]) - for key, value in context_global.application.write().items(): - self.assertEqual(value, mock_sender.data.tags[key]) - for key, value in context_global.user.write().items(): - self.assertEqual(value, mock_sender.data.tags[key]) - for key, value in context_global.session.write().items(): - self.assertEqual(value, mock_sender.data.tags[key]) - for key, value in context_global.location.write().items(): - self.assertEqual(value, mock_sender.data.tags[key]) - for key, value in context_global.operation.write().items(): - self.assertEqual(value, mock_sender.data.tags[key]) - self.assertIsNotNone(mock_sender.data.data) - self.assertEqual(item.DATA_TYPE_NAME, mock_sender.data.data.base_type) - self.assertEqual(item, mock_sender.data.data.base_data) - - -class MockQueue(object): - def __init__(self): - self.flush_count = 0 - - def flush(self): - self.flush_count += 1 - - -class MockTelemetrySender(channel.TelemetryChannel().sender.__class__): - def __init__(self): - self.data = None - self.send_buffer_size = 1 - - def send(self, envelope): - self.data = envelope[0]; diff --git a/tests/applicationinsights_tests/channel_tests/TestTelemetryContext.py b/tests/applicationinsights_tests/channel_tests/TestTelemetryContext.py deleted file mode 100644 index 9dda8569..00000000 --- a/tests/applicationinsights_tests/channel_tests/TestTelemetryContext.py +++ /dev/null @@ -1,122 +0,0 @@ -import unittest -import platform -import locale - -import sys, os, os.path -rootDirectory = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', '..', '..') -if rootDirectory not in sys.path: - sys.path.append(rootDirectory) - -from applicationinsights import channel - - -class TestTelemetryContext(unittest.TestCase): - def test_construct(self): - context = channel.TelemetryContext() - self.assertIsNone(context.instrumentation_key) - self.assertIsNotNone(context.device) - self.assertEqual("Other", context.device.type) - self.assertEqual(platform.node(), context.device.id) - self.assertEqual(platform.version(), context.device.os_version) - self.assertEqual(locale.getdefaultlocale()[0], context.device.locale) - self.assertIsNotNone(context.cloud) - self.assertIsNotNone(context.application) - self.assertIsNotNone(context.user) - self.assertIsNotNone(context.session) - self.assertIsNotNone(context.operation) - self.assertIsNotNone(context.location) - self.assertIsNotNone(context.properties) - - def test_instrumentation_key_attribute_works_as_expected(self): - context = channel.TelemetryContext() - self.assertIsNone(context.instrumentation_key) - context.instrumentation_key = "foo" - self.assertEqual("foo", context.instrumentation_key) - - def test_device_attribute_works_as_expected(self): - context = channel.TelemetryContext() - self.assertIsNotNone(context.device) - context.device = None - self.assertIsNone(context.device) - context.device = Exception() - self.assertIsNotNone(context.device) - self.assertIsInstance(context.device, Exception) - context.device = channel.contracts.Device() - self.assertIsNotNone(context.device) - self.assertIsInstance(context.device, channel.contracts.Device) - - def test_cloud_attribute_works_as_expected(self): - context = channel.TelemetryContext() - self.assertIsNotNone(context.cloud) - context.cloud = None - self.assertIsNone(context.cloud) - context.cloud = Exception() - self.assertIsNotNone(context.cloud) - self.assertIsInstance(context.cloud, Exception) - context.cloud = channel.contracts.Cloud() - self.assertIsNotNone(context.cloud) - self.assertIsInstance(context.cloud, channel.contracts.Cloud) - - def test_application_attribute_works_as_expected(self): - context = channel.TelemetryContext() - self.assertIsNotNone(context.application) - context.application = None - self.assertIsNone(context.application) - context.application = Exception() - self.assertIsNotNone(context.application) - self.assertIsInstance(context.application, Exception) - context.application = channel.contracts.Application() - self.assertIsNotNone(context.application) - self.assertIsInstance(context.application, channel.contracts.Application) - - def test_user_attribute_works_as_expected(self): - context = channel.TelemetryContext() - self.assertIsNotNone(context.user) - context.user = None - self.assertIsNone(context.user) - context.user = Exception() - self.assertIsNotNone(context.user) - self.assertIsInstance(context.user, Exception) - context.user = channel.contracts.User() - self.assertIsNotNone(context.user) - self.assertIsInstance(context.user, channel.contracts.User) - - def test_session_attribute_works_as_expected(self): - context = channel.TelemetryContext() - self.assertIsNotNone(context.session) - context.session = None - self.assertIsNone(context.session) - context.session = Exception() - self.assertIsNotNone(context.session) - self.assertIsInstance(context.session, Exception) - context.session = channel.contracts.Session() - self.assertIsNotNone(context.session) - self.assertIsInstance(context.session, channel.contracts.Session) - - def test_location_attribute_works_as_expected(self): - context = channel.TelemetryContext() - self.assertIsNotNone(context.location) - context.location = None - self.assertIsNone(context.location) - context.location = Exception() - self.assertIsNotNone(context.location) - self.assertIsInstance(context.location, Exception) - context.location = channel.contracts.Location() - self.assertIsNotNone(context.location) - self.assertIsInstance(context.location, channel.contracts.Location) - - def test_operation_attribute_works_as_expected(self): - context = channel.TelemetryContext() - self.assertIsNotNone(context.operation) - context.operation = None - self.assertIsNone(context.operation) - context.operation = Exception() - self.assertIsNotNone(context.operation) - self.assertIsInstance(context.operation, Exception) - context.operation = channel.contracts.Operation() - self.assertIsNotNone(context.operation) - self.assertIsInstance(context.operation, channel.contracts.Operation) - - def test_properties_property_works_as_expected(self): - context = channel.TelemetryContext() - self.assertIsNotNone(context.properties) diff --git a/tests/applicationinsights_tests/channel_tests/__init__.py b/tests/applicationinsights_tests/channel_tests/__init__.py deleted file mode 100644 index d7ac7abf..00000000 --- a/tests/applicationinsights_tests/channel_tests/__init__.py +++ /dev/null @@ -1,9 +0,0 @@ -from . import TestAsynchronousQueue -from . import TestAsynchronousSender -from . import TestQueueBase -from . import TestSenderBase -from . import TestSynchronousQueue -from . import TestSynchronousSender -from . import TestTelemetryChannel -from . import TestTelemetryContext -from . import contracts_tests \ No newline at end of file diff --git a/tests/applicationinsights_tests/channel_tests/contracts_tests/TestApplication.py b/tests/applicationinsights_tests/channel_tests/contracts_tests/TestApplication.py deleted file mode 100644 index 05f3e782..00000000 --- a/tests/applicationinsights_tests/channel_tests/contracts_tests/TestApplication.py +++ /dev/null @@ -1,37 +0,0 @@ -import unittest -import datetime -import uuid -import sys -import json - -import sys, os, os.path -root_directory = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', '..', '..', '..') -if root_directory not in sys.path: - sys.path.append(root_directory) - -from applicationinsights.channel.contracts import * -from .Utils import TestJsonEncoder - -class TestApplication(unittest.TestCase): - def test_construct(self): - item = Application() - self.assertNotEqual(item, None) - - def test_ver_property_works_as_expected(self): - expected = 'Test string' - item = Application() - item.ver = expected - actual = item.ver - self.assertEqual(expected, actual) - expected = 'Other string' - item.ver = expected - actual = item.ver - self.assertEqual(expected, actual) - - def test_serialize_works_as_expected(self): - item = Application() - item.ver = 'Test string' - actual = json.dumps(item.write(), separators=(',', ':'), cls=TestJsonEncoder) - expected = '{"ai.application.ver":"Test string"}' - self.assertEqual(expected, actual) - diff --git a/tests/applicationinsights_tests/channel_tests/contracts_tests/TestData.py b/tests/applicationinsights_tests/channel_tests/contracts_tests/TestData.py deleted file mode 100644 index 2aabe8e4..00000000 --- a/tests/applicationinsights_tests/channel_tests/contracts_tests/TestData.py +++ /dev/null @@ -1,49 +0,0 @@ -import unittest -import datetime -import uuid -import sys -import json - -import sys, os, os.path -root_directory = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', '..', '..', '..') -if root_directory not in sys.path: - sys.path.append(root_directory) - -from applicationinsights.channel.contracts import * -from .Utils import TestJsonEncoder - -class TestData(unittest.TestCase): - def test_construct(self): - item = Data() - self.assertNotEqual(item, None) - - def test_base_type_property_works_as_expected(self): - expected = 'Test string' - item = Data() - item.base_type = expected - actual = item.base_type - self.assertEqual(expected, actual) - expected = 'Other string' - item.base_type = expected - actual = item.base_type - self.assertEqual(expected, actual) - - def test_base_data_property_works_as_expected(self): - expected = object() - item = Data() - item.base_data = expected - actual = item.base_data - self.assertEqual(expected, actual) - expected = object() - item.base_data = expected - actual = item.base_data - self.assertEqual(expected, actual) - - def test_serialize_works_as_expected(self): - item = Data() - item.base_type = 'Test string' - item.base_data = object() - actual = json.dumps(item.write(), separators=(',', ':'), cls=TestJsonEncoder) - expected = '{"baseType":"Test string","baseData":{}}' - self.assertEqual(expected, actual) - diff --git a/tests/applicationinsights_tests/channel_tests/contracts_tests/TestDataPoint.py b/tests/applicationinsights_tests/channel_tests/contracts_tests/TestDataPoint.py deleted file mode 100644 index 7a92259f..00000000 --- a/tests/applicationinsights_tests/channel_tests/contracts_tests/TestDataPoint.py +++ /dev/null @@ -1,109 +0,0 @@ -import unittest -import datetime -import uuid -import sys -import json - -import sys, os, os.path -root_directory = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', '..', '..', '..') -if root_directory not in sys.path: - sys.path.append(root_directory) - -from applicationinsights.channel.contracts import * -from .Utils import TestJsonEncoder - -class TestDataPoint(unittest.TestCase): - def test_construct(self): - item = DataPoint() - self.assertNotEqual(item, None) - - def test_name_property_works_as_expected(self): - expected = 'Test string' - item = DataPoint() - item.name = expected - actual = item.name - self.assertEqual(expected, actual) - expected = 'Other string' - item.name = expected - actual = item.name - self.assertEqual(expected, actual) - - def test_kind_property_works_as_expected(self): - expected = object() - item = DataPoint() - item.kind = expected - actual = item.kind - self.assertEqual(expected, actual) - expected = object() - item.kind = expected - actual = item.kind - self.assertEqual(expected, actual) - - def test_value_property_works_as_expected(self): - expected = 1.5 - item = DataPoint() - item.value = expected - actual = item.value - self.assertEqual(expected, actual) - expected = 4.8 - item.value = expected - actual = item.value - self.assertEqual(expected, actual) - - def test_count_property_works_as_expected(self): - expected = 42 - item = DataPoint() - item.count = expected - actual = item.count - self.assertEqual(expected, actual) - expected = 13 - item.count = expected - actual = item.count - self.assertEqual(expected, actual) - - def test_min_property_works_as_expected(self): - expected = 1.5 - item = DataPoint() - item.min = expected - actual = item.min - self.assertEqual(expected, actual) - expected = 4.8 - item.min = expected - actual = item.min - self.assertEqual(expected, actual) - - def test_max_property_works_as_expected(self): - expected = 1.5 - item = DataPoint() - item.max = expected - actual = item.max - self.assertEqual(expected, actual) - expected = 4.8 - item.max = expected - actual = item.max - self.assertEqual(expected, actual) - - def test_std_dev_property_works_as_expected(self): - expected = 1.5 - item = DataPoint() - item.std_dev = expected - actual = item.std_dev - self.assertEqual(expected, actual) - expected = 4.8 - item.std_dev = expected - actual = item.std_dev - self.assertEqual(expected, actual) - - def test_serialize_works_as_expected(self): - item = DataPoint() - item.name = 'Test string' - item.kind = object() - item.value = 1.5 - item.count = 42 - item.min = 1.5 - item.max = 1.5 - item.std_dev = 1.5 - actual = json.dumps(item.write(), separators=(',', ':'), cls=TestJsonEncoder) - expected = '{"name":"Test string","kind":{},"value":1.5,"count":42,"min":1.5,"max":1.5,"stdDev":1.5}' - self.assertEqual(expected, actual) - diff --git a/tests/applicationinsights_tests/channel_tests/contracts_tests/TestDevice.py b/tests/applicationinsights_tests/channel_tests/contracts_tests/TestDevice.py deleted file mode 100644 index 9657ce4e..00000000 --- a/tests/applicationinsights_tests/channel_tests/contracts_tests/TestDevice.py +++ /dev/null @@ -1,185 +0,0 @@ -import unittest -import datetime -import uuid -import sys -import json - -import sys, os, os.path -root_directory = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', '..', '..', '..') -if root_directory not in sys.path: - sys.path.append(root_directory) - -from applicationinsights.channel.contracts import Device -from .Utils import TestJsonEncoder - -class TestDevice(unittest.TestCase): - def test_construct(self): - item = Device() - self.assertNotEqual(item, None) - - def test_id_property_works_as_expected(self): - expected = 'Test string' - item = Device() - item.id = expected - actual = item.id - self.assertEqual(expected, actual) - expected = 'Other string' - item.id = expected - actual = item.id - self.assertEqual(expected, actual) - - def test_ip_property_works_as_expected(self): - expected = 'Test string' - item = Device() - item.ip = expected - actual = item.ip - self.assertEqual(expected, actual) - expected = 'Other string' - item.ip = expected - actual = item.ip - self.assertEqual(expected, actual) - - def test_language_property_works_as_expected(self): - expected = 'Test string' - item = Device() - item.language = expected - actual = item.language - self.assertEqual(expected, actual) - expected = 'Other string' - item.language = expected - actual = item.language - self.assertEqual(expected, actual) - - def test_locale_property_works_as_expected(self): - expected = 'Test string' - item = Device() - item.locale = expected - actual = item.locale - self.assertEqual(expected, actual) - expected = 'Other string' - item.locale = expected - actual = item.locale - self.assertEqual(expected, actual) - - def test_model_property_works_as_expected(self): - expected = 'Test string' - item = Device() - item.model = expected - actual = item.model - self.assertEqual(expected, actual) - expected = 'Other string' - item.model = expected - actual = item.model - self.assertEqual(expected, actual) - - def test_network_property_works_as_expected(self): - expected = 'Test string' - item = Device() - item.network = expected - actual = item.network - self.assertEqual(expected, actual) - expected = 'Other string' - item.network = expected - actual = item.network - self.assertEqual(expected, actual) - - def test_oem_name_property_works_as_expected(self): - expected = 'Test string' - item = Device() - item.oem_name = expected - actual = item.oem_name - self.assertEqual(expected, actual) - expected = 'Other string' - item.oem_name = expected - actual = item.oem_name - self.assertEqual(expected, actual) - - def test_os_property_works_as_expected(self): - expected = 'Test string' - item = Device() - item.os = expected - actual = item.os - self.assertEqual(expected, actual) - expected = 'Other string' - item.os = expected - actual = item.os - self.assertEqual(expected, actual) - - def test_os_version_property_works_as_expected(self): - expected = 'Test string' - item = Device() - item.os_version = expected - actual = item.os_version - self.assertEqual(expected, actual) - expected = 'Other string' - item.os_version = expected - actual = item.os_version - self.assertEqual(expected, actual) - - def test_role_instance_property_works_as_expected(self): - expected = 'Test string' - item = Device() - item.role_instance = expected - actual = item.role_instance - self.assertEqual(expected, actual) - expected = 'Other string' - item.role_instance = expected - actual = item.role_instance - self.assertEqual(expected, actual) - - def test_role_name_property_works_as_expected(self): - expected = 'Test string' - item = Device() - item.role_name = expected - actual = item.role_name - self.assertEqual(expected, actual) - expected = 'Other string' - item.role_name = expected - actual = item.role_name - self.assertEqual(expected, actual) - - def test_screen_resolution_property_works_as_expected(self): - expected = 'Test string' - item = Device() - item.screen_resolution = expected - actual = item.screen_resolution - self.assertEqual(expected, actual) - expected = 'Other string' - item.screen_resolution = expected - actual = item.screen_resolution - self.assertEqual(expected, actual) - - def test_type_property_works_as_expected(self): - expected = 'Test string' - item = Device() - item.type = expected - actual = item.type - self.assertEqual(expected, actual) - expected = 'Other string' - item.type = expected - actual = item.type - self.assertEqual(expected, actual) - - def test_vm_name_property_works_as_expected(self): - expected = 'Test string' - item = Device() - item.vm_name = expected - actual = item.vm_name - self.assertEqual(expected, actual) - expected = 'Other string' - item.vm_name = expected - actual = item.vm_name - self.assertEqual(expected, actual) - - def test_serialize_works_as_expected(self): - item = Device() - item.id = 'Test string' - item.locale = 'Test string' - item.model = 'Test string' - item.oem_name = 'Test string' - item.os_version = 'Test string' - item.type = 'Test string' - actual = json.dumps(item.write(), separators=(',', ':'), cls=TestJsonEncoder) - expected = '{"ai.device.id":"Test string","ai.device.locale":"Test string","ai.device.model":"Test string","ai.device.oemName":"Test string","ai.device.osVersion":"Test string","ai.device.type":"Test string"}' - self.assertEqual(expected, actual) - diff --git a/tests/applicationinsights_tests/channel_tests/contracts_tests/TestEnvelope.py b/tests/applicationinsights_tests/channel_tests/contracts_tests/TestEnvelope.py deleted file mode 100644 index 7e1fb121..00000000 --- a/tests/applicationinsights_tests/channel_tests/contracts_tests/TestEnvelope.py +++ /dev/null @@ -1,193 +0,0 @@ -import unittest -import datetime -import uuid -import sys -import json - -import sys, os, os.path -root_directory = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', '..', '..', '..') -if root_directory not in sys.path: - sys.path.append(root_directory) - -from applicationinsights.channel.contracts import Envelope -from .Utils import TestJsonEncoder - -class TestEnvelope(unittest.TestCase): - def test_construct(self): - item = Envelope() - self.assertNotEqual(item, None) - - def test_ver_property_works_as_expected(self): - expected = 42 - item = Envelope() - item.ver = expected - actual = item.ver - self.assertEqual(expected, actual) - expected = 13 - item.ver = expected - actual = item.ver - self.assertEqual(expected, actual) - - def test_name_property_works_as_expected(self): - expected = 'Test string' - item = Envelope() - item.name = expected - actual = item.name - self.assertEqual(expected, actual) - expected = 'Other string' - item.name = expected - actual = item.name - self.assertEqual(expected, actual) - - def test_time_property_works_as_expected(self): - expected = 'Test string' - item = Envelope() - item.time = expected - actual = item.time - self.assertEqual(expected, actual) - expected = 'Other string' - item.time = expected - actual = item.time - self.assertEqual(expected, actual) - - def test_sample_rate_property_works_as_expected(self): - expected = 1.5 - item = Envelope() - item.sample_rate = expected - actual = item.sample_rate - self.assertEqual(expected, actual) - expected = 4.8 - item.sample_rate = expected - actual = item.sample_rate - self.assertEqual(expected, actual) - - def test_seq_property_works_as_expected(self): - expected = 'Test string' - item = Envelope() - item.seq = expected - actual = item.seq - self.assertEqual(expected, actual) - expected = 'Other string' - item.seq = expected - actual = item.seq - self.assertEqual(expected, actual) - - def test_ikey_property_works_as_expected(self): - expected = 'Test string' - item = Envelope() - item.ikey = expected - actual = item.ikey - self.assertEqual(expected, actual) - expected = 'Other string' - item.ikey = expected - actual = item.ikey - self.assertEqual(expected, actual) - - def test_flags_property_works_as_expected(self): - expected = 42 - item = Envelope() - item.flags = expected - actual = item.flags - self.assertEqual(expected, actual) - expected = 13 - item.flags = expected - actual = item.flags - self.assertEqual(expected, actual) - - def test_device_id_property_works_as_expected(self): - expected = 'Test string' - item = Envelope() - item.device_id = expected - actual = item.device_id - self.assertEqual(expected, actual) - expected = 'Other string' - item.device_id = expected - actual = item.device_id - self.assertEqual(expected, actual) - - def test_os_property_works_as_expected(self): - expected = 'Test string' - item = Envelope() - item.os = expected - actual = item.os - self.assertEqual(expected, actual) - expected = 'Other string' - item.os = expected - actual = item.os - self.assertEqual(expected, actual) - - def test_os_ver_property_works_as_expected(self): - expected = 'Test string' - item = Envelope() - item.os_ver = expected - actual = item.os_ver - self.assertEqual(expected, actual) - expected = 'Other string' - item.os_ver = expected - actual = item.os_ver - self.assertEqual(expected, actual) - - def test_app_id_property_works_as_expected(self): - expected = 'Test string' - item = Envelope() - item.app_id = expected - actual = item.app_id - self.assertEqual(expected, actual) - expected = 'Other string' - item.app_id = expected - actual = item.app_id - self.assertEqual(expected, actual) - - def test_app_ver_property_works_as_expected(self): - expected = 'Test string' - item = Envelope() - item.app_ver = expected - actual = item.app_ver - self.assertEqual(expected, actual) - expected = 'Other string' - item.app_ver = expected - actual = item.app_ver - self.assertEqual(expected, actual) - - def test_user_id_property_works_as_expected(self): - expected = 'Test string' - item = Envelope() - item.user_id = expected - actual = item.user_id - self.assertEqual(expected, actual) - expected = 'Other string' - item.user_id = expected - actual = item.user_id - self.assertEqual(expected, actual) - - def test_tags_property_works_as_expected(self): - item = Envelope() - actual = item.tags - self.assertNotEqual(actual, None) - - def test_data_property_works_as_expected(self): - expected = object() - item = Envelope() - item.data = expected - actual = item.data - self.assertEqual(expected, actual) - expected = object() - item.data = expected - actual = item.data - self.assertEqual(expected, actual) - - def test_serialize_works_as_expected(self): - item = Envelope() - item.ver = 42 - item.name = 'Test string' - item.time = 'Test string' - item.sample_rate = 1.5 - item.seq = 'Test string' - item.ikey = 'Test string' - for key, value in { 'key1': 'test value 1' , 'key2': 'test value 2' }.items(): - item.tags[key] = value - item.data = object() - actual = json.dumps(item.write(), separators=(',', ':'), cls=TestJsonEncoder) - expected = '{"ver":42,"name":"Test string","time":"Test string","sampleRate":1.5,"seq":"Test string","iKey":"Test string","tags":{"key1":"test value 1","key2":"test value 2"},"data":{}}' - self.assertEqual(expected, actual) - diff --git a/tests/applicationinsights_tests/channel_tests/contracts_tests/TestEventData.py b/tests/applicationinsights_tests/channel_tests/contracts_tests/TestEventData.py deleted file mode 100644 index 5c25265a..00000000 --- a/tests/applicationinsights_tests/channel_tests/contracts_tests/TestEventData.py +++ /dev/null @@ -1,63 +0,0 @@ -import unittest -import datetime -import uuid -import sys -import json - -import sys, os, os.path -root_directory = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', '..', '..', '..') -if root_directory not in sys.path: - sys.path.append(root_directory) - -from applicationinsights.channel.contracts import * -from .Utils import TestJsonEncoder - -class TestEventData(unittest.TestCase): - def test_construct(self): - item = EventData() - self.assertNotEqual(item, None) - - def test_ver_property_works_as_expected(self): - expected = 42 - item = EventData() - item.ver = expected - actual = item.ver - self.assertEqual(expected, actual) - expected = 13 - item.ver = expected - actual = item.ver - self.assertEqual(expected, actual) - - def test_name_property_works_as_expected(self): - expected = 'Test string' - item = EventData() - item.name = expected - actual = item.name - self.assertEqual(expected, actual) - expected = 'Other string' - item.name = expected - actual = item.name - self.assertEqual(expected, actual) - - def test_properties_property_works_as_expected(self): - item = EventData() - actual = item.properties - self.assertNotEqual(actual, None) - - def test_measurements_property_works_as_expected(self): - item = EventData() - actual = item.measurements - self.assertNotEqual(actual, None) - - def test_serialize_works_as_expected(self): - item = EventData() - item.ver = 42 - item.name = 'Test string' - for key, value in { 'key1': 'test value 1' , 'key2': 'test value 2' }.items(): - item.properties[key] = value - for key, value in { 'key1': 3.1415 , 'key2': 42.2 }.items(): - item.measurements[key] = value - actual = json.dumps(item.write(), separators=(',', ':'), cls=TestJsonEncoder) - expected = '{"ver":42,"name":"Test string","properties":{"key1":"test value 1","key2":"test value 2"},"measurements":{"key1":3.1415,"key2":42.2}}' - self.assertEqual(expected, actual) - diff --git a/tests/applicationinsights_tests/channel_tests/contracts_tests/TestExceptionData.py b/tests/applicationinsights_tests/channel_tests/contracts_tests/TestExceptionData.py deleted file mode 100644 index 01f50899..00000000 --- a/tests/applicationinsights_tests/channel_tests/contracts_tests/TestExceptionData.py +++ /dev/null @@ -1,83 +0,0 @@ -import unittest -import datetime -import uuid -import sys -import json - -import sys, os, os.path -root_directory = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', '..', '..', '..') -if root_directory not in sys.path: - sys.path.append(root_directory) - -from applicationinsights.channel.contracts import ExceptionData, ExceptionDetails -from .Utils import TestJsonEncoder - -class TestExceptionData(unittest.TestCase): - def test_construct(self): - item = ExceptionData() - self.assertNotEqual(item, None) - - def test_ver_property_works_as_expected(self): - expected = 42 - item = ExceptionData() - item.ver = expected - actual = item.ver - self.assertEqual(expected, actual) - expected = 13 - item.ver = expected - actual = item.ver - self.assertEqual(expected, actual) - - def test_handled_at_property_works_as_expected(self): - expected = 'Test string' - item = ExceptionData() - item.handled_at = expected - actual = item.handled_at - self.assertEqual(expected, actual) - expected = 'Other string' - item.handled_at = expected - actual = item.handled_at - self.assertEqual(expected, actual) - - def test_exceptions_property_works_as_expected(self): - item = ExceptionData() - actual = item.exceptions - self.assertNotEqual(actual, None) - - def test_severity_level_property_works_as_expected(self): - expected = object() - item = ExceptionData() - item.severity_level = expected - actual = item.severity_level - self.assertEqual(expected, actual) - expected = object() - item.severity_level = expected - actual = item.severity_level - self.assertEqual(expected, actual) - - def test_properties_property_works_as_expected(self): - item = ExceptionData() - actual = item.properties - self.assertNotEqual(actual, None) - - def test_measurements_property_works_as_expected(self): - item = ExceptionData() - actual = item.measurements - self.assertNotEqual(actual, None) - - def test_serialize_works_as_expected(self): - item = ExceptionData() - item.ver = 42 - item.handled_at = 'Test string' - for value in [ object() ]: - item.exceptions.append(value) - - item.severity_level = object() - for key, value in { 'key1': 'test value 1' , 'key2': 'test value 2' }.items(): - item.properties[key] = value - for key, value in { 'key1': 3.1415 , 'key2': 42.2 }.items(): - item.measurements[key] = value - actual = json.dumps(item.write(), separators=(',', ':'), cls=TestJsonEncoder) - expected = '{"ver":42,"exceptions":[{}],"severityLevel":{},"properties":{"key1":"test value 1","key2":"test value 2"},"measurements":{"key1":3.1415,"key2":42.2}}' - self.assertEqual(expected, actual) - diff --git a/tests/applicationinsights_tests/channel_tests/contracts_tests/TestExceptionDetails.py b/tests/applicationinsights_tests/channel_tests/contracts_tests/TestExceptionDetails.py deleted file mode 100644 index 5f190799..00000000 --- a/tests/applicationinsights_tests/channel_tests/contracts_tests/TestExceptionDetails.py +++ /dev/null @@ -1,105 +0,0 @@ -import unittest -import datetime -import uuid -import sys -import json - -import sys, os, os.path -root_directory = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', '..', '..', '..') -if root_directory not in sys.path: - sys.path.append(root_directory) - -from applicationinsights.channel.contracts import * -from .Utils import TestJsonEncoder - -class TestExceptionDetails(unittest.TestCase): - def test_construct(self): - item = ExceptionDetails() - self.assertNotEqual(item, None) - - def test_id_property_works_as_expected(self): - expected = 42 - item = ExceptionDetails() - item.id = expected - actual = item.id - self.assertEqual(expected, actual) - expected = 13 - item.id = expected - actual = item.id - self.assertEqual(expected, actual) - - def test_outer_id_property_works_as_expected(self): - expected = 42 - item = ExceptionDetails() - item.outer_id = expected - actual = item.outer_id - self.assertEqual(expected, actual) - expected = 13 - item.outer_id = expected - actual = item.outer_id - self.assertEqual(expected, actual) - - def test_type_name_property_works_as_expected(self): - expected = 'Test string' - item = ExceptionDetails() - item.type_name = expected - actual = item.type_name - self.assertEqual(expected, actual) - expected = 'Other string' - item.type_name = expected - actual = item.type_name - self.assertEqual(expected, actual) - - def test_message_property_works_as_expected(self): - expected = 'Test string' - item = ExceptionDetails() - item.message = expected - actual = item.message - self.assertEqual(expected, actual) - expected = 'Other string' - item.message = expected - actual = item.message - self.assertEqual(expected, actual) - - def test_has_full_stack_property_works_as_expected(self): - expected = True - item = ExceptionDetails() - item.has_full_stack = expected - actual = item.has_full_stack - self.assertEqual(expected, actual) - expected = False - item.has_full_stack = expected - actual = item.has_full_stack - self.assertEqual(expected, actual) - - def test_stack_property_works_as_expected(self): - expected = 'Test string' - item = ExceptionDetails() - item.stack = expected - actual = item.stack - self.assertEqual(expected, actual) - expected = 'Other string' - item.stack = expected - actual = item.stack - self.assertEqual(expected, actual) - - def test_parsed_stack_property_works_as_expected(self): - item = ExceptionDetails() - actual = item.parsed_stack - self.assertNotEqual(actual, None) - - def test_serialize_works_as_expected(self): - item = ExceptionDetails() - item.id = 42 - item.outer_id = 42 - item.type_name = 'Test string' - item.message = 'Test string' - item.has_full_stack = True - item.stack = 'Test string' - for value in [ object() ]: - item.parsed_stack.append(value) - - actual = json.dumps(item.write(), separators=(',', ':'), cls=TestJsonEncoder) - expected = '{"id":42,"outerId":42,"typeName":"Test string","message":"Test string","hasFullStack":true,"stack":"Test string","parsedStack":[{}]}' - self.assertEqual(expected, actual) - diff --git a/tests/applicationinsights_tests/channel_tests/contracts_tests/TestInternal.py b/tests/applicationinsights_tests/channel_tests/contracts_tests/TestInternal.py deleted file mode 100644 index 55297ec0..00000000 --- a/tests/applicationinsights_tests/channel_tests/contracts_tests/TestInternal.py +++ /dev/null @@ -1,49 +0,0 @@ -import unittest -import datetime -import uuid -import sys -import json - -import sys, os, os.path -root_directory = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', '..', '..', '..') -if root_directory not in sys.path: - sys.path.append(root_directory) - -from applicationinsights.channel.contracts import * -from .Utils import TestJsonEncoder - -class TestInternal(unittest.TestCase): - def test_construct(self): - item = Internal() - self.assertNotEqual(item, None) - - def test_sdk_version_property_works_as_expected(self): - expected = 'Test string' - item = Internal() - item.sdk_version = expected - actual = item.sdk_version - self.assertEqual(expected, actual) - expected = 'Other string' - item.sdk_version = expected - actual = item.sdk_version - self.assertEqual(expected, actual) - - def test_agent_version_property_works_as_expected(self): - expected = 'Test string' - item = Internal() - item.agent_version = expected - actual = item.agent_version - self.assertEqual(expected, actual) - expected = 'Other string' - item.agent_version = expected - actual = item.agent_version - self.assertEqual(expected, actual) - - def test_serialize_works_as_expected(self): - item = Internal() - item.sdk_version = 'Test string' - item.agent_version = 'Test string' - actual = json.dumps(item.write(), separators=(',', ':'), cls=TestJsonEncoder) - expected = '{"ai.internal.sdkVersion":"Test string","ai.internal.agentVersion":"Test string"}' - self.assertEqual(expected, actual) - diff --git a/tests/applicationinsights_tests/channel_tests/contracts_tests/TestLocation.py b/tests/applicationinsights_tests/channel_tests/contracts_tests/TestLocation.py deleted file mode 100644 index 438708a7..00000000 --- a/tests/applicationinsights_tests/channel_tests/contracts_tests/TestLocation.py +++ /dev/null @@ -1,37 +0,0 @@ -import unittest -import datetime -import uuid -import sys -import json - -import sys, os, os.path -root_directory = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', '..', '..', '..') -if root_directory not in sys.path: - sys.path.append(root_directory) - -from applicationinsights.channel.contracts import * -from .Utils import TestJsonEncoder - -class TestLocation(unittest.TestCase): - def test_construct(self): - item = Location() - self.assertNotEqual(item, None) - - def test_ip_property_works_as_expected(self): - expected = 'Test string' - item = Location() - item.ip = expected - actual = item.ip - self.assertEqual(expected, actual) - expected = 'Other string' - item.ip = expected - actual = item.ip - self.assertEqual(expected, actual) - - def test_serialize_works_as_expected(self): - item = Location() - item.ip = 'Test string' - actual = json.dumps(item.write(), separators=(',', ':'), cls=TestJsonEncoder) - expected = '{"ai.location.ip":"Test string"}' - self.assertEqual(expected, actual) - diff --git a/tests/applicationinsights_tests/channel_tests/contracts_tests/TestMessageData.py b/tests/applicationinsights_tests/channel_tests/contracts_tests/TestMessageData.py deleted file mode 100644 index 91d88a5e..00000000 --- a/tests/applicationinsights_tests/channel_tests/contracts_tests/TestMessageData.py +++ /dev/null @@ -1,68 +0,0 @@ -import unittest -import datetime -import uuid -import sys -import json - -import sys, os, os.path -root_directory = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', '..', '..', '..') -if root_directory not in sys.path: - sys.path.append(root_directory) - -from applicationinsights.channel.contracts import * -from .Utils import TestJsonEncoder - -class TestMessageData(unittest.TestCase): - def test_construct(self): - item = MessageData() - self.assertNotEqual(item, None) - - def test_ver_property_works_as_expected(self): - expected = 42 - item = MessageData() - item.ver = expected - actual = item.ver - self.assertEqual(expected, actual) - expected = 13 - item.ver = expected - actual = item.ver - self.assertEqual(expected, actual) - - def test_message_property_works_as_expected(self): - expected = 'Test string' - item = MessageData() - item.message = expected - actual = item.message - self.assertEqual(expected, actual) - expected = 'Other string' - item.message = expected - actual = item.message - self.assertEqual(expected, actual) - - def test_severity_level_property_works_as_expected(self): - expected = object() - item = MessageData() - item.severity_level = expected - actual = item.severity_level - self.assertEqual(expected, actual) - expected = object() - item.severity_level = expected - actual = item.severity_level - self.assertEqual(expected, actual) - - def test_properties_property_works_as_expected(self): - item = MessageData() - actual = item.properties - self.assertNotEqual(actual, None) - - def test_serialize_works_as_expected(self): - item = MessageData() - item.ver = 42 - item.message = 'Test string' - item.severity_level = object() - for key, value in { 'key1': 'test value 1' , 'key2': 'test value 2' }.items(): - item.properties[key] = value - actual = json.dumps(item.write(), separators=(',', ':'), cls=TestJsonEncoder) - expected = '{"ver":42,"message":"Test string","severityLevel":{},"properties":{"key1":"test value 1","key2":"test value 2"}}' - self.assertEqual(expected, actual) - diff --git a/tests/applicationinsights_tests/channel_tests/contracts_tests/TestMetricData.py b/tests/applicationinsights_tests/channel_tests/contracts_tests/TestMetricData.py deleted file mode 100644 index c3773968..00000000 --- a/tests/applicationinsights_tests/channel_tests/contracts_tests/TestMetricData.py +++ /dev/null @@ -1,52 +0,0 @@ -import unittest -import datetime -import uuid -import sys -import json - -import sys, os, os.path -root_directory = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', '..', '..', '..') -if root_directory not in sys.path: - sys.path.append(root_directory) - -from applicationinsights.channel.contracts import * -from .Utils import TestJsonEncoder - -class TestMetricData(unittest.TestCase): - def test_construct(self): - item = MetricData() - self.assertNotEqual(item, None) - - def test_ver_property_works_as_expected(self): - expected = 42 - item = MetricData() - item.ver = expected - actual = item.ver - self.assertEqual(expected, actual) - expected = 13 - item.ver = expected - actual = item.ver - self.assertEqual(expected, actual) - - def test_metrics_property_works_as_expected(self): - item = MetricData() - actual = item.metrics - self.assertNotEqual(actual, None) - - def test_properties_property_works_as_expected(self): - item = MetricData() - actual = item.properties - self.assertNotEqual(actual, None) - - def test_serialize_works_as_expected(self): - item = MetricData() - item.ver = 42 - for value in [ object() ]: - item.metrics.append(value) - - for key, value in { 'key1': 'test value 1' , 'key2': 'test value 2' }.items(): - item.properties[key] = value - actual = json.dumps(item.write(), separators=(',', ':'), cls=TestJsonEncoder) - expected = '{"ver":42,"metrics":[{}],"properties":{"key1":"test value 1","key2":"test value 2"}}' - self.assertEqual(expected, actual) - diff --git a/tests/applicationinsights_tests/channel_tests/contracts_tests/TestOperation.py b/tests/applicationinsights_tests/channel_tests/contracts_tests/TestOperation.py deleted file mode 100644 index 3c05603d..00000000 --- a/tests/applicationinsights_tests/channel_tests/contracts_tests/TestOperation.py +++ /dev/null @@ -1,69 +0,0 @@ -import unittest -import datetime -import uuid -import sys -import json - -import sys, os, os.path -root_directory = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', '..', '..', '..') -if root_directory not in sys.path: - sys.path.append(root_directory) - -from applicationinsights.channel.contracts import Operation -from .Utils import TestJsonEncoder - -class TestOperation(unittest.TestCase): - def test_construct(self): - item = Operation() - self.assertNotEqual(item, None) - - def test_id_property_works_as_expected(self): - expected = 'Test string' - item = Operation() - item.id = expected - actual = item.id - self.assertEqual(expected, actual) - expected = 'Other string' - item.id = expected - actual = item.id - self.assertEqual(expected, actual) - - def test_name_property_works_as_expected(self): - expected = 'Test string' - item = Operation() - item.name = expected - actual = item.name - self.assertEqual(expected, actual) - expected = 'Other string' - item.name = expected - actual = item.name - self.assertEqual(expected, actual) - - def test_parent_id_property_works_as_expected(self): - expected = 'Test string' - item = Operation() - item.parent_id = expected - actual = item.parent_id - self.assertEqual(expected, actual) - expected = 'Other string' - item.parent_id = expected - actual = item.parent_id - self.assertEqual(expected, actual) - - def test_root_id_property_works_as_expected(self): - expected = 'Test string' - item = Operation() - item.root_id = expected - actual = item.root_id - self.assertEqual(expected, actual) - expected = 'Other string' - - def test_serialize_works_as_expected(self): - item = Operation() - item.id = 'Test string' - item.name = 'Test string' - item.parent_id = 'Test string' - actual = json.dumps(item.write(), separators=(',', ':'), cls=TestJsonEncoder) - expected = '{"ai.operation.id":"Test string","ai.operation.name":"Test string","ai.operation.parentId":"Test string"}' - self.assertEqual(expected, actual) - diff --git a/tests/applicationinsights_tests/channel_tests/contracts_tests/TestPageViewData.py b/tests/applicationinsights_tests/channel_tests/contracts_tests/TestPageViewData.py deleted file mode 100644 index 924f73f3..00000000 --- a/tests/applicationinsights_tests/channel_tests/contracts_tests/TestPageViewData.py +++ /dev/null @@ -1,87 +0,0 @@ -import unittest -import datetime -import uuid -import sys -import json - -import sys, os, os.path -root_directory = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', '..', '..', '..') -if root_directory not in sys.path: - sys.path.append(root_directory) - -from applicationinsights.channel.contracts import * -from .Utils import TestJsonEncoder - -class TestPageViewData(unittest.TestCase): - def test_construct(self): - item = PageViewData() - self.assertNotEqual(item, None) - - def test_ver_property_works_as_expected(self): - expected = 42 - item = PageViewData() - item.ver = expected - actual = item.ver - self.assertEqual(expected, actual) - expected = 13 - item.ver = expected - actual = item.ver - self.assertEqual(expected, actual) - - def test_url_property_works_as_expected(self): - expected = 'Test string' - item = PageViewData() - item.url = expected - actual = item.url - self.assertEqual(expected, actual) - expected = 'Other string' - item.url = expected - actual = item.url - self.assertEqual(expected, actual) - - def test_name_property_works_as_expected(self): - expected = 'Test string' - item = PageViewData() - item.name = expected - actual = item.name - self.assertEqual(expected, actual) - expected = 'Other string' - item.name = expected - actual = item.name - self.assertEqual(expected, actual) - - def test_duration_property_works_as_expected(self): - expected = 'Test string' - item = PageViewData() - item.duration = expected - actual = item.duration - self.assertEqual(expected, actual) - expected = 'Other string' - item.duration = expected - actual = item.duration - self.assertEqual(expected, actual) - - def test_properties_property_works_as_expected(self): - item = PageViewData() - actual = item.properties - self.assertNotEqual(actual, None) - - def test_measurements_property_works_as_expected(self): - item = PageViewData() - actual = item.measurements - self.assertNotEqual(actual, None) - - def test_serialize_works_as_expected(self): - item = PageViewData() - item.ver = 42 - item.url = 'Test string' - item.name = 'Test string' - item.duration = 'Test string' - for key, value in { 'key1': 'test value 1' , 'key2': 'test value 2' }.items(): - item.properties[key] = value - for key, value in { 'key1': 3.1415 , 'key2': 42.2 }.items(): - item.measurements[key] = value - actual = json.dumps(item.write(), separators=(',', ':'), cls=TestJsonEncoder) - expected = '{"ver":42,"url":"Test string","name":"Test string","duration":"Test string","properties":{"key1":"test value 1","key2":"test value 2"},"measurements":{"key1":3.1415,"key2":42.2}}' - self.assertEqual(expected, actual) - diff --git a/tests/applicationinsights_tests/channel_tests/contracts_tests/TestRemoteDependencyData.py b/tests/applicationinsights_tests/channel_tests/contracts_tests/TestRemoteDependencyData.py deleted file mode 100644 index d8f9fdc7..00000000 --- a/tests/applicationinsights_tests/channel_tests/contracts_tests/TestRemoteDependencyData.py +++ /dev/null @@ -1,160 +0,0 @@ -import unittest -import datetime -import uuid -import sys -import json - -import sys, os, os.path -root_directory = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', '..', '..', '..') -if root_directory not in sys.path: - sys.path.append(root_directory) - -from applicationinsights.channel.contracts import RemoteDependencyData -from .Utils import TestJsonEncoder - -class TestRemoteDependencyData(unittest.TestCase): - def test_construct(self): - item = RemoteDependencyData() - self.assertNotEqual(item, None) - - def test_ver_property_works_as_expected(self): - expected = 42 - item = RemoteDependencyData() - item.ver = expected - actual = item.ver - self.assertEqual(expected, actual) - expected = 13 - item.ver = expected - actual = item.ver - self.assertEqual(expected, actual) - - def test_name_property_works_as_expected(self): - expected = 'Test string' - item = RemoteDependencyData() - item.name = expected - actual = item.name - self.assertEqual(expected, actual) - expected = 'Other string' - item.name = expected - actual = item.name - self.assertEqual(expected, actual) - - def test_kind_property_works_as_expected(self): - expected = object() - item = RemoteDependencyData() - item.kind = expected - actual = item.kind - self.assertEqual(expected, actual) - expected = object() - item.kind = expected - actual = item.kind - self.assertEqual(expected, actual) - - def test_value_property_works_as_expected(self): - expected = 1.5 - item = RemoteDependencyData() - item.value = expected - actual = item.value - self.assertEqual(expected, actual) - expected = 4.8 - item.value = expected - actual = item.value - self.assertEqual(expected, actual) - - def test_count_property_works_as_expected(self): - expected = 42 - item = RemoteDependencyData() - item.count = expected - actual = item.count - self.assertEqual(expected, actual) - expected = 13 - item.count = expected - actual = item.count - self.assertEqual(expected, actual) - - def test_min_property_works_as_expected(self): - expected = 1.5 - item = RemoteDependencyData() - item.min = expected - actual = item.min - self.assertEqual(expected, actual) - expected = 4.8 - item.min = expected - actual = item.min - self.assertEqual(expected, actual) - - def test_max_property_works_as_expected(self): - expected = 1.5 - item = RemoteDependencyData() - item.max = expected - actual = item.max - self.assertEqual(expected, actual) - expected = 4.8 - item.max = expected - actual = item.max - self.assertEqual(expected, actual) - - def test_std_dev_property_works_as_expected(self): - expected = 1.5 - item = RemoteDependencyData() - item.std_dev = expected - actual = item.std_dev - self.assertEqual(expected, actual) - expected = 4.8 - item.std_dev = expected - actual = item.std_dev - self.assertEqual(expected, actual) - - def test_dependency_kind_property_works_as_expected(self): - expected = object() - item = RemoteDependencyData() - item.dependency_kind = expected - actual = item.dependency_kind - self.assertEqual(expected, actual) - expected = object() - item.dependency_kind = expected - actual = item.dependency_kind - self.assertEqual(expected, actual) - - def test_success_property_works_as_expected(self): - expected = True - item = RemoteDependencyData() - item.success = expected - actual = item.success - self.assertEqual(expected, actual) - expected = False - item.success = expected - actual = item.success - self.assertEqual(expected, actual) - - def test_dependency_source_property_works_as_expected(self): - expected = object() - item = RemoteDependencyData() - item.dependency_source = expected - actual = item.dependency_source - self.assertEqual(expected, actual) - expected = object() - item.dependency_source = expected - actual = item.dependency_source - self.assertEqual(expected, actual) - - def test_properties_property_works_as_expected(self): - item = RemoteDependencyData() - actual = item.properties - self.assertNotEqual(actual, None) - - def test_serialize_works_as_expected(self): - item = RemoteDependencyData() - item.ver = 42 - item.name = 'Test string' - item.kind = object() - item.duration = 1.5 - item.dependency_kind = object() - item.success = True - item.dependency_source = object() - for key, value in { 'key1': 'test value 1' , 'key2': 'test value 2' }.items(): - item.properties[key] = value - actual = json.dumps(item.write(), separators=(',', ':'), cls=TestJsonEncoder) - expected = '{"ver":42,"name":"Test string","duration":1.5,"success":true,"properties":{"key1":"test value 1","key2":"test value 2"}}' - self.assertEqual(expected, actual) - diff --git a/tests/applicationinsights_tests/channel_tests/contracts_tests/TestRequestData.py b/tests/applicationinsights_tests/channel_tests/contracts_tests/TestRequestData.py deleted file mode 100644 index be8a1870..00000000 --- a/tests/applicationinsights_tests/channel_tests/contracts_tests/TestRequestData.py +++ /dev/null @@ -1,145 +0,0 @@ -import unittest -import datetime -import uuid -import sys -import json - -import sys, os, os.path -root_directory = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', '..', '..', '..') -if root_directory not in sys.path: - sys.path.append(root_directory) - -from applicationinsights.channel.contracts import RequestData -from .Utils import TestJsonEncoder - -class TestRequestData(unittest.TestCase): - def test_construct(self): - item = RequestData() - self.assertNotEqual(item, None) - - def test_ver_property_works_as_expected(self): - expected = 42 - item = RequestData() - item.ver = expected - actual = item.ver - self.assertEqual(expected, actual) - expected = 13 - item.ver = expected - actual = item.ver - self.assertEqual(expected, actual) - - def test_id_property_works_as_expected(self): - expected = 'Test string' - item = RequestData() - item.id = expected - actual = item.id - self.assertEqual(expected, actual) - expected = 'Other string' - item.id = expected - actual = item.id - self.assertEqual(expected, actual) - - def test_name_property_works_as_expected(self): - expected = 'Test string' - item = RequestData() - item.name = expected - actual = item.name - self.assertEqual(expected, actual) - expected = 'Other string' - item.name = expected - actual = item.name - self.assertEqual(expected, actual) - - def test_start_time_property_works_as_expected(self): - expected = 'Test string' - item = RequestData() - item.start_time = expected - actual = item.start_time - self.assertEqual(expected, actual) - expected = 'Other string' - item.start_time = expected - actual = item.start_time - self.assertEqual(expected, actual) - - def test_duration_property_works_as_expected(self): - expected = 'Test string' - item = RequestData() - item.duration = expected - actual = item.duration - self.assertEqual(expected, actual) - expected = 'Other string' - item.duration = expected - actual = item.duration - self.assertEqual(expected, actual) - - def test_response_code_property_works_as_expected(self): - expected = 'Test string' - item = RequestData() - item.response_code = expected - actual = item.response_code - self.assertEqual(expected, actual) - expected = 'Other string' - item.response_code = expected - actual = item.response_code - self.assertEqual(expected, actual) - - def test_success_property_works_as_expected(self): - expected = True - item = RequestData() - item.success = expected - actual = item.success - self.assertEqual(expected, actual) - expected = False - item.success = expected - actual = item.success - self.assertEqual(expected, actual) - - def test_http_method_property_works_as_expected(self): - expected = 'Test string' - item = RequestData() - item.http_method = expected - actual = item.http_method - self.assertEqual(expected, actual) - expected = 'Other string' - item.http_method = expected - actual = item.http_method - self.assertEqual(expected, actual) - - def test_url_property_works_as_expected(self): - expected = 'Test string' - item = RequestData() - item.url = expected - actual = item.url - self.assertEqual(expected, actual) - expected = 'Other string' - item.url = expected - actual = item.url - self.assertEqual(expected, actual) - - def test_properties_property_works_as_expected(self): - item = RequestData() - actual = item.properties - self.assertNotEqual(actual, None) - - def test_measurements_property_works_as_expected(self): - item = RequestData() - actual = item.measurements - self.assertNotEqual(actual, None) - - def test_serialize_works_as_expected(self): - item = RequestData() - item.ver = 42 - item.id = 'Test string' - item.name = 'Test string' - item.duration = 'Test string' - item.response_code = 'Test string' - item.success = True - item.url = 'Test string' - for key, value in { 'key1': 'test value 1' , 'key2': 'test value 2' }.items(): - item.properties[key] = value - for key, value in { 'key1': 3.1415 , 'key2': 42.2 }.items(): - item.measurements[key] = value - actual = json.dumps(item.write(), separators=(',', ':'), cls=TestJsonEncoder) - expected = '{"ver":42,"id":"Test string","name":"Test string","duration":"Test string","responseCode":"Test string","success":true,"url":"Test string","properties":{"key1":"test value 1","key2":"test value 2"},"measurements":{"key1":3.1415,"key2":42.2}}' - self.assertEqual(expected, actual) - diff --git a/tests/applicationinsights_tests/channel_tests/contracts_tests/TestSession.py b/tests/applicationinsights_tests/channel_tests/contracts_tests/TestSession.py deleted file mode 100644 index cf44b3cb..00000000 --- a/tests/applicationinsights_tests/channel_tests/contracts_tests/TestSession.py +++ /dev/null @@ -1,60 +0,0 @@ -import unittest -import datetime -import uuid -import sys -import json - -import sys, os, os.path -root_directory = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', '..', '..', '..') -if root_directory not in sys.path: - sys.path.append(root_directory) - -from applicationinsights.channel.contracts import Session -from .Utils import TestJsonEncoder - -class TestSession(unittest.TestCase): - def test_construct(self): - item = Session() - self.assertNotEqual(item, None) - - def test_id_property_works_as_expected(self): - expected = 'Test string' - item = Session() - item.id = expected - actual = item.id - self.assertEqual(expected, actual) - expected = 'Other string' - item.id = expected - actual = item.id - self.assertEqual(expected, actual) - - def test_is_first_property_works_as_expected(self): - expected = 'Test string' - item = Session() - item.is_first = expected - actual = item.is_first - self.assertEqual(expected, actual) - expected = 'Other string' - item.is_first = expected - actual = item.is_first - self.assertEqual(expected, actual) - - def test_is_new_property_works_as_expected(self): - expected = 'Test string' - item = Session() - item.is_new = expected - actual = item.is_new - self.assertEqual(expected, actual) - expected = 'Other string' - item.is_new = expected - actual = item.is_new - self.assertEqual(expected, actual) - - def test_serialize_works_as_expected(self): - item = Session() - item.id = 'Test string' - item.is_first = 'Test string' - actual = json.dumps(item.write(), separators=(',', ':'), cls=TestJsonEncoder) - expected = '{"ai.session.id":"Test string","ai.session.isFirst":"Test string"}' - self.assertEqual(expected, actual) - diff --git a/tests/applicationinsights_tests/channel_tests/contracts_tests/TestStackFrame.py b/tests/applicationinsights_tests/channel_tests/contracts_tests/TestStackFrame.py deleted file mode 100644 index b9723944..00000000 --- a/tests/applicationinsights_tests/channel_tests/contracts_tests/TestStackFrame.py +++ /dev/null @@ -1,85 +0,0 @@ -import unittest -import datetime -import uuid -import sys -import json - -import sys, os, os.path -root_directory = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', '..', '..', '..') -if root_directory not in sys.path: - sys.path.append(root_directory) - -from applicationinsights.channel.contracts import * -from .Utils import TestJsonEncoder - -class TestStackFrame(unittest.TestCase): - def test_construct(self): - item = StackFrame() - self.assertNotEqual(item, None) - - def test_level_property_works_as_expected(self): - expected = 42 - item = StackFrame() - item.level = expected - actual = item.level - self.assertEqual(expected, actual) - expected = 13 - item.level = expected - actual = item.level - self.assertEqual(expected, actual) - - def test_method_property_works_as_expected(self): - expected = 'Test string' - item = StackFrame() - item.method = expected - actual = item.method - self.assertEqual(expected, actual) - expected = 'Other string' - item.method = expected - actual = item.method - self.assertEqual(expected, actual) - - def test_assembly_property_works_as_expected(self): - expected = 'Test string' - item = StackFrame() - item.assembly = expected - actual = item.assembly - self.assertEqual(expected, actual) - expected = 'Other string' - item.assembly = expected - actual = item.assembly - self.assertEqual(expected, actual) - - def test_file_name_property_works_as_expected(self): - expected = 'Test string' - item = StackFrame() - item.file_name = expected - actual = item.file_name - self.assertEqual(expected, actual) - expected = 'Other string' - item.file_name = expected - actual = item.file_name - self.assertEqual(expected, actual) - - def test_line_property_works_as_expected(self): - expected = 42 - item = StackFrame() - item.line = expected - actual = item.line - self.assertEqual(expected, actual) - expected = 13 - item.line = expected - actual = item.line - self.assertEqual(expected, actual) - - def test_serialize_works_as_expected(self): - item = StackFrame() - item.level = 42 - item.method = 'Test string' - item.assembly = 'Test string' - item.file_name = 'Test string' - item.line = 42 - actual = json.dumps(item.write(), separators=(',', ':'), cls=TestJsonEncoder) - expected = '{"level":42,"method":"Test string","assembly":"Test string","fileName":"Test string","line":42}' - self.assertEqual(expected, actual) - diff --git a/tests/applicationinsights_tests/channel_tests/contracts_tests/TestUser.py b/tests/applicationinsights_tests/channel_tests/contracts_tests/TestUser.py deleted file mode 100644 index 69664ad3..00000000 --- a/tests/applicationinsights_tests/channel_tests/contracts_tests/TestUser.py +++ /dev/null @@ -1,71 +0,0 @@ -import unittest -import datetime -import uuid -import sys -import json - -import sys, os, os.path -root_directory = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', '..', '..', '..') -if root_directory not in sys.path: - sys.path.append(root_directory) - -from applicationinsights.channel.contracts import User -from .Utils import TestJsonEncoder - -class TestUser(unittest.TestCase): - def test_construct(self): - item = User() - self.assertNotEqual(item, None) - - def test_account_acquisition_date_property_works_as_expected(self): - expected = 'Test string' - item = User() - item.account_acquisition_date = expected - actual = item.account_acquisition_date - self.assertEqual(expected, actual) - expected = 'Other string' - item.account_acquisition_date = expected - actual = item.account_acquisition_date - self.assertEqual(expected, actual) - - def test_account_id_property_works_as_expected(self): - expected = 'Test string' - item = User() - item.account_id = expected - actual = item.account_id - self.assertEqual(expected, actual) - expected = 'Other string' - item.account_id = expected - actual = item.account_id - self.assertEqual(expected, actual) - - def test_user_agent_property_works_as_expected(self): - expected = 'Test string' - item = User() - item.user_agent = expected - actual = item.user_agent - self.assertEqual(expected, actual) - expected = 'Other string' - item.user_agent = expected - actual = item.user_agent - self.assertEqual(expected, actual) - - def test_id_property_works_as_expected(self): - expected = 'Test string' - item = User() - item.id = expected - actual = item.id - self.assertEqual(expected, actual) - expected = 'Other string' - item.id = expected - actual = item.id - self.assertEqual(expected, actual) - - def test_serialize_works_as_expected(self): - item = User() - item.account_id = 'Test string' - item.id = 'Test string' - actual = json.dumps(item.write(), separators=(',', ':'), cls=TestJsonEncoder) - expected = '{"ai.user.accountId":"Test string","ai.user.id":"Test string"}' - self.assertEqual(expected, actual) - diff --git a/tests/applicationinsights_tests/channel_tests/contracts_tests/Utils.py b/tests/applicationinsights_tests/channel_tests/contracts_tests/Utils.py deleted file mode 100644 index 559f90e0..00000000 --- a/tests/applicationinsights_tests/channel_tests/contracts_tests/Utils.py +++ /dev/null @@ -1,7 +0,0 @@ -import json - -class TestJsonEncoder(json.JSONEncoder): - def default(self, obj): - if obj and obj.__class__.__name__ == 'object': - return {} - return json.JSONEncoder.default(self, obj) \ No newline at end of file diff --git a/tests/applicationinsights_tests/channel_tests/contracts_tests/__init__.py b/tests/applicationinsights_tests/channel_tests/contracts_tests/__init__.py deleted file mode 100644 index 28ae7ab0..00000000 --- a/tests/applicationinsights_tests/channel_tests/contracts_tests/__init__.py +++ /dev/null @@ -1,19 +0,0 @@ -from .TestData import TestData -from .TestEnvelope import TestEnvelope -from .TestDataPoint import TestDataPoint -from .TestMetricData import TestMetricData -from .TestRemoteDependencyData import TestRemoteDependencyData -from .TestRequestData import TestRequestData -from .TestStackFrame import TestStackFrame -from .TestExceptionDetails import TestExceptionDetails -from .TestExceptionData import TestExceptionData -from .TestMessageData import TestMessageData -from .TestEventData import TestEventData -from .TestPageViewData import TestPageViewData -from .TestApplication import TestApplication -from .TestDevice import TestDevice -from .TestLocation import TestLocation -from .TestOperation import TestOperation -from .TestSession import TestSession -from .TestUser import TestUser -from .TestInternal import TestInternal diff --git a/tests/applicationinsights_tests/exception_tests/TestEnable.py b/tests/applicationinsights_tests/exception_tests/TestEnable.py deleted file mode 100644 index 064ef460..00000000 --- a/tests/applicationinsights_tests/exception_tests/TestEnable.py +++ /dev/null @@ -1,48 +0,0 @@ -import unittest - -import sys, os, os.path -rootDirectory = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', '..') -if rootDirectory not in sys.path: - sys.path.append(rootDirectory) - -from applicationinsights import channel, exceptions - - -class TestEnable(unittest.TestCase): - def test_enable(self): - original = sys.excepthook - sys.excepthook = mock_excepthook - sender = MockSynchronousSender() - queue = channel.SynchronousQueue(sender) - telemetry_channel = channel.TelemetryChannel(None, queue) - telemetry_channel.context.properties["foo"] = "bar" - telemetry_channel.context.operation.id = 1001 - exceptions.enable('foo', telemetry_channel=telemetry_channel) - try: - raise Exception('Boom') - except: - sys.excepthook(*sys.exc_info()) - sys.excepthook = original - data = sender.data[0][0] - self.assertIsNotNone(data) - self.assertEqual('foo', data.ikey) - self.assertEqual('Microsoft.ApplicationInsights.Exception', data.name) - self.assertEqual('bar', data.data.base_data.properties['foo']) - self.assertEqual(1001, data.tags.get('ai.operation.id')) - - def test_enable_raises_exception_on_no_instrumentation_key(self): - self.assertRaises(Exception, exceptions.enable, None) - - -def mock_excepthook(type, value, tb): - pass - - -class MockSynchronousSender: - def __init__(self): - self.send_buffer_size = 1 - self.data = [] - self.queue = None - - def send(self, data_to_send): - self.data.append(data_to_send) \ No newline at end of file diff --git a/tests/applicationinsights_tests/exception_tests/__init__.py b/tests/applicationinsights_tests/exception_tests/__init__.py deleted file mode 100644 index f7148325..00000000 --- a/tests/applicationinsights_tests/exception_tests/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from . import TestEnable \ No newline at end of file diff --git a/tests/applicationinsights_tests/logging_tests/TestLoggingHandler.py b/tests/applicationinsights_tests/logging_tests/TestLoggingHandler.py deleted file mode 100644 index aef22130..00000000 --- a/tests/applicationinsights_tests/logging_tests/TestLoggingHandler.py +++ /dev/null @@ -1,168 +0,0 @@ -import unittest -import logging as pylogging - -import sys, os, os.path - -from applicationinsights.channel import AsynchronousQueue, AsynchronousSender -from applicationinsights.channel import SynchronousQueue, SynchronousSender - -rootDirectory = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', '..') -if rootDirectory not in sys.path: - sys.path.append(rootDirectory) - -from applicationinsights import logging -from applicationinsights.logging.LoggingHandler import enabled_instrumentation_keys - -class TestEnable(unittest.TestCase): - def test_enable(self): - handler1 = logging.enable('foo') - self.assertIsNotNone(handler1) - self.assertEqual('LoggingHandler', handler1.__class__.__name__) - self.assertEqual('foo', handler1.client.context.instrumentation_key) - self.assertIsInstance(handler1.client.channel.queue, SynchronousQueue) - self.assertIsInstance(handler1.client.channel.sender, SynchronousSender) - handler2 = logging.enable('foo') - self.assertEqual('LoggingHandler', handler2.__class__.__name__) - self.assertEqual('foo', handler2.client.context.instrumentation_key) - channel = MockChannel() - handler3 = logging.enable('bar', telemetry_channel=channel) - self.assertIsNotNone(handler1) - self.assertEqual('LoggingHandler', handler3.__class__.__name__) - self.assertEqual('bar', handler3.client.context.instrumentation_key) - self.assertEqual(channel, handler3.client.channel) - all_handlers = pylogging.getLogger().handlers - self.assertIn(handler2, all_handlers) - self.assertIn(handler3, all_handlers) - pylogging.getLogger().removeHandler(handler2) - pylogging.getLogger().removeHandler(handler3) - - def test_enable_with_endpoint(self): - handler = logging.enable('foo', endpoint='http://bar') - self.assertEqual(handler.client.channel.sender.service_endpoint_uri, 'http://bar') - pylogging.getLogger().removeHandler(handler) - - def test_enable_with_async(self): - handler = logging.enable('foo', async_=True) - self.assertIsInstance(handler.client.channel.queue, AsynchronousQueue) - self.assertIsInstance(handler.client.channel.sender, AsynchronousSender) - pylogging.getLogger().removeHandler(handler) - - def test_enable_raises_exception_on_async_with_telemetry_channel(self): - with self.assertRaises(Exception): - logging.enable('foo', async_=True, telemetry_channel=MockChannel()) - - def test_enable_raises_exception_on_endpoint_with_telemetry_channel(self): - with self.assertRaises(Exception): - logging.enable('foo', endpoint='http://bar', telemetry_channel=MockChannel()) - - def test_enable_with_level(self): - handler = logging.enable('foo', level='DEBUG') - self.assertIsNotNone(handler) - self.assertEqual(handler.level, pylogging.DEBUG) - pylogging.getLogger().removeHandler(handler) - - def test_enable_raises_exception_on_no_instrumentation_key(self): - self.assertRaises(Exception, logging.enable, None) - - def test_handler_removal_clears_cache(self): - def enable_telemetry(): - logging.enable('key1') - - def remove_telemetry_handlers(): - for handler in pylogging.getLogger().handlers: - if isinstance(handler, logging.LoggingHandler): - pylogging.getLogger().removeHandler(handler) - - enable_telemetry() - self.assertIn('key1', enabled_instrumentation_keys) - remove_telemetry_handlers() - self.assertNotIn('key1', enabled_instrumentation_keys) - - -class TestLoggingHandler(unittest.TestCase): - def test_construct(self): - handler = logging.LoggingHandler('test') - self.assertIsNotNone(handler) - self.assertEqual('test', handler.client.context.instrumentation_key) - - def test_construct_raises_exception_on_no_instrumentation_key(self): - self.assertRaises(Exception, logging.LoggingHandler, None) - - def test_log_works_as_expected(self): - logger, sender, channel = self._setup_logger() - - expected = [ - (logger.debug, 'debug message', 'Microsoft.ApplicationInsights.Message', 'test', 'MessageData', 0, 'simple_logger - DEBUG - debug message'), - (logger.info, 'info message', 'Microsoft.ApplicationInsights.Message', 'test', 'MessageData', 1, 'simple_logger - INFO - info message'), - (logger.warn, 'warn message', 'Microsoft.ApplicationInsights.Message', 'test', 'MessageData', 2, 'simple_logger - WARNING - warn message'), - (logger.error, 'error message', 'Microsoft.ApplicationInsights.Message', 'test', 'MessageData', 3, 'simple_logger - ERROR - error message'), - (logger.critical, 'critical message', 'Microsoft.ApplicationInsights.Message', 'test', 'MessageData', 4, 'simple_logger - CRITICAL - critical message') - ] - - for logging_function, logging_parameter, envelope_type, ikey, data_type, severity_level, message in expected: - logging_function(logging_parameter) - data = sender.data[0][0] - sender.data = [] - self.assertEqual(envelope_type, data.name) - self.assertEqual(ikey, data.ikey) - self.assertEqual(data_type, data.data.base_type) - self.assertEqual(message, data.data.base_data.message) - self.assertEqual(severity_level, data.data.base_data.severity_level) - - channel.context.properties['foo'] = 'bar' - channel.context.operation.id = 1001 - logger.info('info message') - data = sender.data[0][0] - self.assertEqual('bar', data.data.base_data.properties['foo']) - self.assertEqual(1001, data.tags.get('ai.operation.id')) - - def test_log_exception_works_as_expected(self): - logger, sender, _ = self._setup_logger() - - try: - raise Exception('blah') - except: - logger.exception('some error') - - data = sender.data[0][0] - self.assertEqual('Microsoft.ApplicationInsights.Exception', data.name) - self.assertEqual('test', data.ikey) - self.assertEqual('ExceptionData', data.data.base_type) - self.assertEqual('blah', data.data.base_data.exceptions[0].message) - - def _setup_logger(self): - logger = pylogging.getLogger('simple_logger') - logger.setLevel(pylogging.DEBUG) - - handler = logging.LoggingHandler('test') - handler.setLevel(pylogging.DEBUG) - - channel = handler.client.channel - - # mock out the sender - sender = MockSynchronousSender() - queue = channel.queue - queue.max_queue_length = 1 - queue._sender = sender - sender.queue = queue - - formatter = pylogging.Formatter('%(name)s - %(levelname)s - %(message)s') - handler.setFormatter(formatter) - logger.addHandler(handler) - - return logger, sender, channel - - -class MockChannel: - def flush(self): - pass - - -class MockSynchronousSender: - def __init__(self): - self.send_buffer_size = 1 - self.data = [] - self.queue = None - - def send(self, data_to_send): - self.data.append(data_to_send) diff --git a/tests/applicationinsights_tests/logging_tests/__init__.py b/tests/applicationinsights_tests/logging_tests/__init__.py deleted file mode 100644 index 2b8c13c8..00000000 --- a/tests/applicationinsights_tests/logging_tests/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from . import TestLoggingHandler \ No newline at end of file diff --git a/tests/applicationinsights_tests/requests_tests/TestWSGIApplication.py b/tests/applicationinsights_tests/requests_tests/TestWSGIApplication.py deleted file mode 100644 index 0c771cc2..00000000 --- a/tests/applicationinsights_tests/requests_tests/TestWSGIApplication.py +++ /dev/null @@ -1,108 +0,0 @@ -import unittest -import wsgiref - -import sys, os, os.path -rootDirectory = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', '..') -if rootDirectory not in sys.path: - sys.path.append(rootDirectory) - -from applicationinsights import requests - -class TestWSGIApplication(unittest.TestCase): - def test_construct(self): - app = mock_app - wrapper = requests.WSGIApplication('foo', app) - self.assertIsNotNone(wrapper) - self.assertIsNotNone(wrapper.client) - self.assertEqual('foo', wrapper.client.context.instrumentation_key) - - def test_construct_raises_exception_on_no_instrumentation_key(self): - self.assertRaises(Exception, requests.WSGIApplication, None, object()) - - def test_construct_raises_exception_on_no_wsgi_application(self): - self.assertRaises(Exception, requests.WSGIApplication, 'foo', None) - - def test_wsgi_works_as_expected(self): - app = mock_app - wrapper = requests.WSGIApplication('test', app) - sender = self._intercept_sender(wrapper) - env = { - 'REQUEST_METHOD': 'PUT', - 'PATH_INFO': '/foo/bar', - 'QUERY_STRING': 'a=b' - } - - result = wrapper(env, mock_start_response) - result_string = None - for part in result: - result_string = part - - data = sender.data[0][0] - self.assertEqual('Microsoft.ApplicationInsights.Request', data.name) - self.assertEqual('test', data.ikey) - self.assertEqual('RequestData', data.data.base_type) - self.assertEqual('PUT', data.data.base_data.http_method) - self.assertEqual('/foo/bar', data.data.base_data.name) - self.assertEqual('201', data.data.base_data.response_code) - self.assertTrue(data.data.base_data.success) - self.assertEqual('http://unknown/foo/bar?a=b', data.data.base_data.url) - self.assertIsNotNone(data.data.base_data.id) - self.assertEqual(b'Hello World!', result_string) - self.assertEqual(1, mock_start_response_calls) - self.assertEqual('201 BLAH', mock_start_response_status) - self.assertEqual([('Content-type', 'text/plain')], mock_start_response_headers) - - def _intercept_sender(self, wsgi_application): - client = wsgi_application.client - - # mock out the sender - sender = MockAsynchronousSender() - queue = client.channel.queue - queue.max_queue_length = 1 - queue._sender = sender - sender.queue = queue - - return sender - - -mock_start_response_calls = 0 -mock_start_response_status = None -mock_start_response_headers = None - - -def mock_start_response(status, headers, exc_info=None): - global mock_start_response_calls - global mock_start_response_status - global mock_start_response_headers - mock_start_response_calls += 1 - mock_start_response_status = status - mock_start_response_headers = headers - - -def mock_app(environ, start_response): - status = '201 BLAH' - headers = [('Content-type', 'text/plain')] - start_response(status, headers) - return [b'Hello World!'] - - -class MockAsynchronousSender: - def __init__(self): - self.send_buffer_size = 1 - self.data = [] - self.queue = None - - def start(self): - while True: - data = [] - while len(data) < self.send_buffer_size: - item = self.queue.get() - if not item: - break - data.append(item) - if len(data) == 0: - break - self.send(data) - - def send(self, data_to_send): - self.data.append(data_to_send) \ No newline at end of file diff --git a/tests/applicationinsights_tests/requests_tests/__init__.py b/tests/applicationinsights_tests/requests_tests/__init__.py deleted file mode 100644 index 45802dca..00000000 --- a/tests/applicationinsights_tests/requests_tests/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from . import TestWSGIApplication diff --git a/tests/test_exporter.py b/tests/test_exporter.py new file mode 100644 index 00000000..21561ac5 --- /dev/null +++ b/tests/test_exporter.py @@ -0,0 +1,38 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import unittest + +from azure.monitor.opentelemetry.exporter import ( + AzureMonitorLogExporter, + AzureMonitorMetricExporter, + AzureMonitorTraceExporter, +) + + +class TestAzureMonitorExporters(unittest.TestCase): + def test_constructors(self): + cs_string = "InstrumentationKey=1234abcd-5678-4efa-8abc-1234567890ab" + for exporter in [ + AzureMonitorLogExporter, + AzureMonitorMetricExporter, + AzureMonitorTraceExporter, + ]: + try: + exporter(connection_string=cs_string) + except Exception as ex: # pylint: disable=broad-except + print(ex) + self.fail( + f"Unexpected exception raised when instantiating {exporter.__name__}" + ) diff --git a/tox.ini b/tox.ini new file mode 100644 index 00000000..52f99c31 --- /dev/null +++ b/tox.ini @@ -0,0 +1,25 @@ +[tox] +skipsdist = True +skip_missing_interpreters = True +envlist = + py3{6,7,8,9,10}-distro + lint + +[testenv] +deps = + -r test-requirements.txt + +commands = + pytest {posargs} + +[testenv:lint] +basepython: python3.9 +recreate = True +deps = + -r lint-requirements.txt + +commands = + black src + isort --recursive src + pylint src + flake8 src