diff --git a/RedHatNLP/CS506_Project_Paper.pdf b/RedHatNLP/CS506_Project_Paper.pdf new file mode 100644 index 00000000..9d8511f7 Binary files /dev/null and b/RedHatNLP/CS506_Project_Paper.pdf differ diff --git a/RedHatNLP/Deliverable2.ipynb b/RedHatNLP/Deliverable2.ipynb new file mode 100644 index 00000000..f70be830 --- /dev/null +++ b/RedHatNLP/Deliverable2.ipynb @@ -0,0 +1,756 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "name": "Due 02/28/2021", + "provenance": [], + "collapsed_sections": [], + "include_colab_link": true + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + } + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "RT1xSMJ40ewc", + "colab": { + "base_uri": "https://localhost:8080/" + }, + "outputId": "292a57a0-8172-4dd3-d388-8b6eecfe4866" + }, + "source": [ + "# Web scraping (Kyle, due 02/26/2021)\n", + "# BeautifulSoup for web scraping\n", + "\n", + "from urllib.request import urlopen\n", + "from bs4 import BeautifulSoup\n", + "from google.colab import files\n", + "import pandas as pd\n", + "import io\n", + "import numpy as np\n", + "import dateutil\n", + "from dateutil import parser\n", + "import textblob\n", + "from textblob import TextBlob\n", + "import nltk\n", + "import requests\n", + "from textblob import Word\n", + "import matplotlib.pyplot as plt\n", + "from nltk.stem.snowball import SnowballStemmer\n", + "nltk.download('punkt')\n", + "\n", + "# upload file\n", + "#uploaded = files.upload()\n", + "#read array\n", + "#df2 = pd.read_csv(io.BytesIO(uploaded['logs - Sheet1.csv']))\n", + "#turn to flat list\n", + "#array_pages = df2.to_numpy()\n", + "#array_pages = np.ndarray.tolist(array_pages)\n", + "#array_pages = [item for sublist in array_pages for item in sublist]\n", + "\n", + "#url core needed to pull\n", + "website = \"https://gcsweb-ci.apps.ci.l2s4.p1.openshiftapps.com\"\n", + "base = \"https://gcsweb-ci.apps.ci.l2s4.p1.openshiftapps.com/gcs/origin-ci-test/logs/canary-release-openshift-origin-installer-e2e-aws-4.5-cnv/\"\n", + "ending = \"build-log.txt\"\n", + "url = \"https://gcsweb-ci.apps.ci.l2s4.p1.openshiftapps.com/gcs/origin-ci-test/logs/canary-release-openshift-origin-installer-e2e-aws-4.5-cnv/1300557127638585344/build-log.txt\"\n", + "page = requests.get(base) \n", + "data = page.text\n", + "soup = BeautifulSoup(data)\n", + "links = []\n", + "for link in soup.find_all('a'):\n", + " links.append(link.get('href'))\n", + "links = links[1:-1]\n", + "\n", + "final_array = []\n", + "# create array of urls\n", + "for x in range(len(links)):\n", + " final_array.append(str(website) + str(links[x]) + str(ending))\n", + "\n", + "\n", + "# pull all urls logs and store in 2-d array where array_of_logs[x] is a build-log file and \n", + "# array_of_logs[x][y] is an individual log line split by new line\n", + "array_of_logs = []\n", + "for x in range(len(final_array)):\n", + " page = urlopen(final_array[x])\n", + " html_bytes = page.read()\n", + " array_of_logs.append(str(html_bytes).split('\\\\n'))\n", + " \n", + "# first log\n", + "print(array_of_logs[0])\n", + "\n", + "\n", + "# Analysis on the log data. Trying to find a framework. API (Ningxiao, Parker, Tianze, Hong)\n", + "# Identify limitations with data and potential risks of achieving project goals.\n", + "\n", + "\n", + "# ******* Tianze *******\n", + "#ignore useless \"Waiting for setup to finish...\"\n", + "def ignoreWaiting(logs):\n", + " for i in range(len(logs)):\n", + " if \"Waiting for setup to finish...\" in logs[i]:\n", + " logs[i]=\"\"\n", + " return logs\n", + "# ******* Tianze *******\n" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "[nltk_data] Downloading package punkt to /root/nltk_data...\n", + "[nltk_data] Unzipping tokenizers/punkt.zip.\n", + "[\"b'2020/09/26 22:20:37 ci-operator version v20200924-c41f44a\", '2020/09/26 22:20:37 No source defined', '2020/09/26 22:20:37 Resolved release latest to registry.svc.ci.openshift.org/ocp/release:4.5-ci', '2020/09/26 22:20:37 Using namespace https://console.svc.ci.openshift.org/k8s/cluster/projects/ci-op-xl3p51qp', '2020/09/26 22:20:37 Running [release-inputs], [images], [release:latest], e2e-aws', '2020/09/26 22:20:37 Creating namespace ci-op-xl3p51qp', '2020/09/26 22:20:37 Setting up pipeline imagestream for the test', '2020/09/26 22:20:37 Created secret e2e-aws-cnv-cluster-profile', '2020/09/26 22:20:37 Created secret pull-secret', '2020/09/26 22:20:37 Created PDB for pods with openshift.io/build.name label', '2020/09/26 22:20:37 Created PDB for pods with created-by-ci label', '2020/09/26 22:20:37 Tagged shared images from ocp/4.5:${component}, images will be pullable from registry.svc.ci.openshift.org/ci-op-xl3p51qp/stable:${component}', '2020/09/26 22:20:44 Importing release image latest', '2020/09/26 22:21:50 Imported release 4.5.0-0.ci-2020-09-22-154858 created at 2020-09-22 15:56:05 +0000 UTC with 110 images to tag release:latest', '2020/09/26 22:21:50 Acquiring lease for \"aws-quota-slice\"', '2020/09/26 22:21:50 Acquired lease \"c7e13d8f-f2a4-4ba7-91c2-53cd46d5c2eb\" for \"aws-quota-slice\"', '2020/09/26 22:21:50 Executing template e2e-aws', '2020/09/26 22:21:50 Creating or restarting template instance', '2020/09/26 22:21:50 Template instance e2e-aws already deleted, do not need to wait any longer', '2020/09/26 22:21:50 Waiting for template instance to be ready', '2020/09/26 22:21:52 Running pod e2e-aws-cnv', '2020/09/26 22:21:55 Container cli in pod e2e-aws-cnv completed successfully', '2020/09/26 22:21:57 Container cli-tests in pod e2e-aws-cnv completed successfully', '2020/09/26 22:56:18 Container setup in pod e2e-aws-cnv completed successfully', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'Waiting for setup to finish...', 'secret/support created', 'which: no docker in (/tmp/shared:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/go/bin:/go/bin)', './hack/deploy.sh', '+ source hack/common.sh', '++ set -e', '++ source hack/defaults', \"+++++ dirname \\\\'hack/defaults[0]\\\\'\", '++++ readlink -e hack/../', '+++ PROJECT_ROOT=/go/src/github.com/kubevirt/hyperconverged-cluster-operator', '+++ source /go/src/github.com/kubevirt/hyperconverged-cluster-operator/hack/config', '++++ KUBEVIRT_VERSION=v0.29.2', '++++ CDI_VERSION=v1.18.0', '++++ NETWORK_ADDONS_VERSION=0.38.0', '++++ SSP_VERSION=v1.0.35', '++++ NMO_VERSION=v0.6.0', '++++ HPPO_VERSION=v0.4.3', '++++ HPP_VERSION=v0.4.0', '++++ CONVERSION_CONTAINER_VERSION=v2.0.0', '++++ VMWARE_CONTAINER_VERSION=v2.0.0-3', '++++ VM_IMPORT_VERSION=v0.0.2', '++++ CONTAINER_REGISTRY=quay.io/kubevirt', '++++ mktemp -d', '+++ TEMP_DIR=/tmp/tmp.rVClBhsVd1', '+++ WAIT_TIMEOUT=450s', '+++ CDI_CONTAINER_REGISTRY=docker.io/kubevirt', '+++ KUBEVIRT_CONTAINER_REGISTRY=docker.io/kubevirt', '+++ NETWORK_ADDONS_CONTAINER_REGISTRY=quay.io/kubevirt', '+++ SSP_CONTAINER_REGISTRY=quay.io/fromani', '+++ CDI_OPERATOR_NAME=cdi-operator', '++++ basename docker.io/kubevirt', '+++ CDI_DOCKER_PREFIX=kubevirt', '+++ CONTROLLER_IMAGE=cdi-controller', '+++ IMPORTER_IMAGE=cdi-importer', '+++ CLONER_IMAGE=cdi-cloner', '+++ APISERVER_IMAGE=cdi-apiserver', '+++ UPLOADPROXY_IMAGE=cdi-uploadproxy', '+++ UPLOADSERVER_IMAGE=cdi-uploadserver', '+++ NETWORK_ADDONS_MULTUS_IMAGE=', '+++ NETWORK_ADDONS_LINUX_BRIDGE_CNI_IMAGE=', '+++ NETWORK_ADDONS_LINUX_BRIDGE_MARKER_IMAGE=', '+++ NETWORK_ADDONS_KUBEMACPOOL_IMAGE=', '+++ NETWORK_ADDONS_NMSTATE_HANDLER_IMAGE=', '+++ NETWORK_ADDONS_OVS_CNI_PLUGIN_IMAGE=', '+++ NETWORK_ADDONS_OVS_CNI_MARKER_IMAGE=', '+++ VM_IMPORT_CONTAINER_REGISTRY=quay.io/kubevirt', '+++ VM_IMPORT_IMAGE=vm-import-operator', '+++ echo docker.io/kubevirt', '+++ grep brew', \"+++ OPERATOR_MANIFESTS=\\\\'https://github.com/kubevirt/kubevirt/releases/download/v0.29.2/kubevirt-operator.yaml\", 'https://github.com/kubevirt/containerized-data-importer/releases/download/v1.18.0/cdi-operator.yaml.j2', 'https://github.com/kubevirt/cluster-network-addons-operator/releases/download/0.38.0/network-addons-config.crd.yaml', 'https://github.com/kubevirt/cluster-network-addons-operator/releases/download/0.38.0/namespace.yaml', 'https://github.com/kubevirt/cluster-network-addons-operator/releases/download/0.38.0/operator.yaml', 'https://github.com/MarSik/kubevirt-ssp-operator/releases/download/v1.0.35/kubevirt-ssp-operator-crd.yaml', 'https://github.com/MarSik/kubevirt-ssp-operator/releases/download/v1.0.35/kubevirt-ssp-operator.yaml', \"https://github.com/kubevirt/vm-import-operator/releases/download/v0.0.2/operator.yaml\\\\'\", \"+++ OPERATOR_CRS=\\\\'https://github.com/kubevirt/kubevirt/releases/download/v0.29.2/kubevirt-cr.yaml\", 'https://github.com/kubevirt/containerized-data-importer/releases/download/v1.18.0/cdi-operator-cr.yaml', 'https://github.com/kubevirt/cluster-network-addons-operator/releases/download/0.38.0/network-addons-config-example.cr.yaml', 'https://github.com/MarSik/kubevirt-ssp-operator/releases/download/v1.0.35/kubevirt-ssp-operator-cr.yaml', \"https://github.com/kubevirt/vm-import-operator/releases/download/v0.0.2/vmimportconfig_cr.yaml\\\\'\", '++ source cluster/kubevirtci.sh', '+++ export KUBEVIRT_PROVIDER=k8s-1.17', '+++ KUBEVIRT_PROVIDER=k8s-1.17', '+++ KUBEVIRTCI_VERSION=9d224d0c22e9ed2ca7588ccf3a258d82e160b195', '+++ KUBEVIRTCI_PATH=/go/src/github.com/kubevirt/hyperconverged-cluster-operator/_kubevirtci', '++ CDI_OPERATOR_URL=https://github.com/kubevirt/containerized-data-importer/releases/download/v1.18.0/cdi-operator.yaml', '++ KUBEVIRT_OPERATOR_URL=https://github.com/kubevirt/kubevirt/releases/download/v0.29.2/kubevirt-operator.yaml', '++ CNA_URL_PREFIX=https://github.com/kubevirt/cluster-network-addons-operator/releases/download/0.38.0', '++ mem_size=5120M', '++ num_nodes=1', '++ KUBEVIRT_PROVIDER=k8s-1.17', '++ BASE_PATH=/go/src/github.com/kubevirt/hyperconverged-cluster-operator', '+++ kubevirtci::path', '+++ echo -n /go/src/github.com/kubevirt/hyperconverged-cluster-operator/_kubevirtci', '++ KUBEVIRTCI_PATH=/go/src/github.com/kubevirt/hyperconverged-cluster-operator/_kubevirtci', '++ CMD=', '++ KUBECTL=', '++ TEST_PATH=tests/func-tests', '++ TEST_OUT_PATH=tests/func-tests/_out', '++ JOB_TYPE=prow', '++ SSP_URL_PREFIX=https://github.com/MarSik/kubevirt-ssp-operator/releases/download/v1.0.35', '++ VM_IMPORT_URL_PREFIX=https://github.com/kubevirt/vm-import-operator/releases/download/v0.0.2', '+++ which kubectl', '++ KUBECTL=/tmp/shared/kubectl', \"++ \\\\'[\\\\' -z \\\\'\\\\' \\\\']\\\\'\", \"++ \\\\'[\\\\' -z /tmp/shared/kubectl \\\\']\\\\'\", '++ CMD=kubectl', '+ HCO_IMAGE=quay.io/kubevirt/hyperconverged-cluster-operator:latest', '+ HCO_NAMESPACE=kubevirt-hyperconverged', '+ HCO_KIND=hyperconvergeds', '+ HCO_RESOURCE_NAME=kubevirt-hyperconverged', '+ CI=', \"+ \\\\'[\\\\' \\\\'\\\\' == CI \\\\']\\\\'\", \"+ \\\\'[\\\\' e2e-aws-cnv == hco-e2e-aws \\\\']\\\\'\", \"+ \\\\'[\\\\' e2e-aws-cnv == e2e-aws-cnv \\\\']\\\\'\", \"+ echo \\\\'deploying on AWS CI\\\\'\", 'deploying on AWS CI', '+ CI=true', '+ rm -rf _out/', '+ cp -r deploy _out/', \"+ \\\\'[\\\\' -n \\\\'registry.svc.ci.openshift.org/ci-op-xl3p51qp/stable:${component}\\\\' \\\\']\\\\'\", '+ component=hyperconverged-cluster-operator', \"++ eval echo \\\\'registry.svc.ci.openshift.org/ci-op-xl3p51qp/stable:${component}\\\\'\", '+++ echo registry.svc.ci.openshift.org/ci-op-xl3p51qp/stable:hyperconverged-cluster-operator', '+ HCO_IMAGE=registry.svc.ci.openshift.org/ci-op-xl3p51qp/stable:hyperconverged-cluster-operator', \"+ sed -i \\\\'s|image: quay.io/kubevirt/hyperconverged-cluster-operator:.*$|image: registry.svc.ci.openshift.org/ci-op-xl3p51qp/stable:hyperconverged-cluster-operator|g\\\\' _out/operator.yaml\", '+ kubectl create ns kubevirt-hyperconverged', '+ true', '+ namespaces=(\"openshift\")', \"+ for namespace in \\\\'${namespaces[@]}\\\\'\", '++ kubectl get ns openshift', '+ [[ NAME STATUS AGE', \"openshift Active 18m == \\\\'\\\\' ]]\", \"+ \\\\'[\\\\' kubectl == oc \\\\']\\\\'\", '++ kubectl config current-context', '+ kubectl config set-context admin --namespace=kubevirt-hyperconverged', 'Context \"admin\" modified.', '+ trap status EXIT', '+ CONTAINER_ERRORED=', '+ kubectl create -f _out/cluster_role.yaml', 'role.rbac.authorization.k8s.io/cluster-network-addons-operator created', 'role.rbac.authorization.k8s.io/kubevirt-operator created', 'role.rbac.authorization.k8s.io/cdi-operator created', 'role.rbac.authorization.k8s.io/hostpath-provisioner-operator created', 'clusterrole.rbac.authorization.k8s.io/hyperconverged-cluster-operator created', 'clusterrole.rbac.authorization.k8s.io/cluster-network-addons-operator created', 'clusterrole.rbac.authorization.k8s.io/kubevirt-operator created', 'clusterrole.rbac.authorization.k8s.io/kubevirt-ssp-operator created', 'clusterrole.rbac.authorization.k8s.io/cdi-operator created', 'clusterrole.rbac.authorization.k8s.io/node-maintenance-operator created', 'clusterrole.rbac.authorization.k8s.io/hostpath-provisioner-operator created', 'clusterrole.rbac.authorization.k8s.io/vm-import-operator created', '+ kubectl create -f _out/service_account.yaml', 'serviceaccount/cdi-operator created', 'serviceaccount/cluster-network-addons-operator created', 'serviceaccount/hostpath-provisioner-operator created', 'serviceaccount/hyperconverged-cluster-operator created', 'serviceaccount/kubevirt-operator created', 'serviceaccount/kubevirt-ssp-operator created', 'serviceaccount/node-maintenance-operator created', 'serviceaccount/vm-import-operator created', '+ kubectl create -f _out/cluster_role_binding.yaml', 'rolebinding.rbac.authorization.k8s.io/cluster-network-addons-operator created', 'rolebinding.rbac.authorization.k8s.io/kubevirt-operator created', 'rolebinding.rbac.authorization.k8s.io/cdi-operator created', 'rolebinding.rbac.authorization.k8s.io/hostpath-provisioner-operator created', 'clusterrolebinding.rbac.authorization.k8s.io/hyperconverged-cluster-operator created', 'clusterrolebinding.rbac.authorization.k8s.io/cluster-network-addons-operator created', 'clusterrolebinding.rbac.authorization.k8s.io/kubevirt-operator created', 'clusterrolebinding.rbac.authorization.k8s.io/kubevirt-ssp-operator created', 'clusterrolebinding.rbac.authorization.k8s.io/cdi-operator created', 'clusterrolebinding.rbac.authorization.k8s.io/node-maintenance-operator created', 'clusterrolebinding.rbac.authorization.k8s.io/hostpath-provisioner-operator created', 'clusterrolebinding.rbac.authorization.k8s.io/vm-import-operator created', '+ kubectl create -f _out/crds/', 'customresourcedefinition.apiextensions.k8s.io/networkaddonsconfigs.networkaddonsoperator.network.kubevirt.io created', 'customresourcedefinition.apiextensions.k8s.io/cdis.cdi.kubevirt.io created', 'customresourcedefinition.apiextensions.k8s.io/hyperconvergeds.hco.kubevirt.io created', 'customresourcedefinition.apiextensions.k8s.io/v2vvmwares.v2v.kubevirt.io created', 'customresourcedefinition.apiextensions.k8s.io/ovirtproviders.v2v.kubevirt.io created', 'customresourcedefinition.apiextensions.k8s.io/hostpathprovisioners.hostpathprovisioner.kubevirt.io created', 'customresourcedefinition.apiextensions.k8s.io/kubevirts.kubevirt.io created', 'customresourcedefinition.apiextensions.k8s.io/nodemaintenances.nodemaintenance.kubevirt.io created', 'customresourcedefinition.apiextensions.k8s.io/kubevirtcommontemplatesbundles.ssp.kubevirt.io created', 'customresourcedefinition.apiextensions.k8s.io/kubevirtmetricsaggregations.ssp.kubevirt.io created', 'customresourcedefinition.apiextensions.k8s.io/kubevirtnodelabellerbundles.ssp.kubevirt.io created', 'customresourcedefinition.apiextensions.k8s.io/kubevirttemplatevalidators.ssp.kubevirt.io created', 'customresourcedefinition.apiextensions.k8s.io/vmimportconfigs.v2v.kubevirt.io created', \"+ \\\\'[\\\\' true \\\\'!=\\\\' true \\\\']\\\\'\", \"+ sed -E \\\\'s|^(\\\\\\\\s*)- name: KVM_EMULATION$|\\\\\\\\1- name: KVM_EMULATION\\\\\", '\\\\\\\\1 value: \"true\"|\\\\\\'', '+ cat _out/operator-ci.yaml', '---', 'apiVersion: apps/v1', 'kind: Deployment', 'metadata:', ' labels:', ' name: hyperconverged-cluster-operator', ' name: hyperconverged-cluster-operator', 'spec:', ' replicas: 1', ' selector:', ' matchLabels:', ' name: hyperconverged-cluster-operator', ' strategy: {}', ' template:', ' metadata:', ' labels:', ' name: hyperconverged-cluster-operator', ' spec:', ' containers:', ' - command:', ' - hyperconverged-cluster-operator', ' env:', ' - name: KVM_EMULATION', ' value: \"true\"', ' - name: OPERATOR_IMAGE', ' value: quay.io/kubevirt/hyperconverged-cluster-operator:1.1.0', ' - name: OPERATOR_NAME', ' value: hyperconverged-cluster-operator', ' - name: OPERATOR_NAMESPACE', ' value: kubevirt-hyperconverged', ' - name: POD_NAME', ' valueFrom:', ' fieldRef:', ' fieldPath: metadata.name', ' - name: WATCH_NAMESPACE', ' - name: CONVERSION_CONTAINER', ' value: quay.io/kubevirt/kubevirt-v2v-conversion:v2.0.0', ' - name: VMWARE_CONTAINER', ' value: quay.io/kubevirt/kubevirt-vmware:v2.0.0-3', ' - name: SMBIOS', ' value: |-', '+ kubectl create -f _out/operator-ci.yaml', ' Family: KubeVirt', ' Manufacturer: KubeVirt', ' Product: None', ' - name: MACHINETYPE', ' - name: HCO_KV_IO_VERSION', ' value: 1.1.0', ' - name: KUBEVIRT_VERSION', ' value: v0.29.2', ' - name: CDI_VERSION', ' value: v1.18.0', ' - name: NETWORK_ADDONS_VERSION', ' value: 0.38.0', ' - name: SSP_VERSION', ' value: v1.0.35', ' - name: NMO_VERSION', ' value: v0.6.0', ' - name: HPPO_VERSION', ' value: v0.4.3', ' - name: VM_IMPORT_VERSION', ' value: v0.0.2', ' image: registry.svc.ci.openshift.org/ci-op-xl3p51qp/stable:hyperconverged-cluster-operator', ' imagePullPolicy: IfNotPresent', ' name: hyperconverged-cluster-operator', ' readinessProbe:', ' exec:', ' command:', ' - stat', ' - /tmp/operator-sdk-ready', ' failureThreshold: 1', ' initialDelaySeconds: 5', ' periodSeconds: 5', ' resources: {}', ' serviceAccountName: hyperconverged-cluster-operator', '---', 'apiVersion: apps/v1', 'kind: Deployment', 'metadata:', ' labels:', ' name: cluster-network-addons-operator', ' name: cluster-network-addons-operator', 'spec:', ' replicas: 1', ' selector:', ' matchLabels:', ' name: cluster-network-addons-operator', ' strategy:', ' type: Recreate', ' template:', ' metadata:', ' labels:', ' name: cluster-network-addons-operator', ' spec:', ' containers:', ' - env:', ' - name: MULTUS_IMAGE', ' value: nfvpe/multus:v3.4.1', ' - name: LINUX_BRIDGE_IMAGE', ' value: quay.io/kubevirt/cni-default-plugins:v0.8.1', ' - name: LINUX_BRIDGE_MARKER_IMAGE', ' value: quay.io/kubevirt/bridge-marker:0.2.0', ' - name: NMSTATE_HANDLER_IMAGE', ' value: quay.io/nmstate/kubernetes-nmstate-handler:v0.20.0', ' - name: OVS_CNI_IMAGE', ' value: quay.io/kubevirt/ovs-cni-plugin:v0.11.0', ' - name: OVS_MARKER_IMAGE', ' value: quay.io/kubevirt/ovs-cni-marker:v0.11.0', ' - name: KUBEMACPOOL_IMAGE', ' value: quay.io/kubevirt/kubemacpool:v0.14.0', ' - name: MACVTAP_CNI_IMAGE', ' value: quay.io/kubevirt/macvtap-cni:v0.2.0', ' - name: OPERATOR_IMAGE', ' value: quay.io/kubevirt/cluster-network-addons-operator:0.38.0', ' - name: OPERATOR_NAME', ' value: cluster-network-addons-operator', ' - name: OPERATOR_VERSION', ' value: 0.38.0', ' - name: OPERATOR_NAMESPACE', ' valueFrom:', ' fieldRef:', ' fieldPath: metadata.namespace', ' - name: OPERAND_NAMESPACE', ' valueFrom:', ' fieldRef:', ' fieldPath: metadata.namespace', ' - name: POD_NAME', ' valueFrom:', ' fieldRef:', ' fieldPath: metadata.name', ' - name: WATCH_NAMESPACE', ' image: quay.io/kubevirt/cluster-network-addons-operator:0.38.0', ' imagePullPolicy: IfNotPresent', ' name: cluster-network-addons-operator', ' resources: {}', ' serviceAccountName: cluster-network-addons-operator', '---', 'apiVersion: apps/v1', 'kind: Deployment', 'metadata:', ' labels:', ' name: virt-operator', ' name: virt-operator', 'spec:', ' replicas: 2', ' selector:', ' matchLabels:', ' kubevirt.io: virt-operator', ' strategy:', ' type: RollingUpdate', ' template:', ' metadata:', ' annotations:', ' scheduler.alpha.kubernetes.io/critical-pod: \"\"', ' labels:', ' kubevirt.io: virt-operator', ' prometheus.kubevirt.io: \"\"', ' name: virt-operator', ' spec:', ' affinity:', ' podAntiAffinity:', ' preferredDuringSchedulingIgnoredDuringExecution:', ' - podAffinityTerm:', ' labelSelector:', ' matchExpressions:', ' - key: kubevirt.io', ' operator: In', ' values:', ' - virt-operator', ' topologyKey: kubernetes.io/hostname', ' weight: 1', ' containers:', ' - command:', ' - virt-operator', ' - --port', ' - \"8443\"', ' - -v', ' - \"2\"', ' env:', ' - name: OPERATOR_IMAGE', ' value: docker.io/kubevirt/virt-operator:v0.29.2', ' - name: WATCH_NAMESPACE', ' valueFrom:', ' fieldRef:', \" fieldPath: metadata.annotations[\\\\'olm.targetNamespaces\\\\']\", ' image: docker.io/kubevirt/virt-operator:v0.29.2', ' imagePullPolicy: IfNotPresent', ' name: virt-operator', ' ports:', ' - containerPort: 8443', ' name: metrics', ' protocol: TCP', ' - containerPort: 8444', ' name: webhooks', ' protocol: TCP', ' readinessProbe:', ' httpGet:', ' path: /metrics', ' port: 8443', ' scheme: HTTPS', ' initialDelaySeconds: 5', ' timeoutSeconds: 10', ' resources: {}', ' volumeMounts:', ' - mountPath: /etc/virt-operator/certificates', ' name: kubevirt-operator-certs', ' readOnly: true', ' priorityClassName: kubevirt-cluster-critical', ' securityContext:', ' runAsNonRoot: true', ' serviceAccountName: kubevirt-operator', ' tolerations:', ' - key: CriticalAddonsOnly', ' operator: Exists', ' volumes:', ' - name: kubevirt-operator-certs', ' secret:', ' optional: true', ' secretName: kubevirt-operator-certs', '---', 'apiVersion: apps/v1', 'kind: Deployment', 'metadata:', ' labels:', ' name: kubevirt-ssp-operator', ' name: kubevirt-ssp-operator', 'spec:', ' replicas: 1', ' selector:', ' matchLabels:', ' name: kubevirt-ssp-operator', ' strategy: {}', ' template:', ' metadata:', ' labels:', ' name: kubevirt-ssp-operator', ' spec:', ' containers:', ' - env:', ' - name: POD_NAME', ' valueFrom:', ' fieldRef:', ' fieldPath: metadata.name', ' - name: IMAGE_REFERENCE', ' value: quay.io/fromani/kubevirt-ssp-operator-container:v1.0.35', ' - name: WATCH_NAMESPACE', ' - name: KVM_INFO_TAG', ' - name: VALIDATOR_TAG', ' - name: VIRT_LAUNCHER_TAG', ' - name: NODE_LABELLER_TAG', ' - name: CPU_PLUGIN_TAG', ' - name: IMAGE_NAME_PREFIX', ' - name: OPERATOR_NAME', ' value: kubevirt-ssp-operator', ' image: quay.io/fromani/kubevirt-ssp-operator-container:v1.0.35', ' imagePullPolicy: Always', ' name: kubevirt-ssp-operator', ' ports:', ' - containerPort: 60000', ' name: metrics', ' resources: {}', ' serviceAccountName: kubevirt-ssp-operator', '---', 'apiVersion: apps/v1', 'kind: Deployment', 'metadata:', ' labels:', ' name: cdi-operator', ' name: cdi-operator', 'spec:', ' replicas: 1', ' selector:', ' matchLabels:', ' name: cdi-operator', ' operator.cdi.kubevirt.io: \"\"', ' strategy: {}', ' template:', ' metadata:', ' labels:', ' name: cdi-operator', ' operator.cdi.kubevirt.io: \"\"', ' spec:', ' containers:', ' - env:', ' - name: DEPLOY_CLUSTER_RESOURCES', ' value: \"true\"', ' - name: OPERATOR_VERSION', ' value: v1.18.0', ' - name: CONTROLLER_IMAGE', ' value: docker.io/kubevirt/cdi-controller:v1.18.0', ' - name: IMPORTER_IMAGE', ' value: docker.io/kubevirt/cdi-importer:v1.18.0', ' - name: CLONER_IMAGE', ' value: docker.io/kubevirt/cdi-cloner:v1.18.0', ' - name: APISERVER_IMAGE', ' value: docker.io/kubevirt/cdi-apiserver:v1.18.0', ' - name: UPLOAD_SERVER_IMAGE', ' value: docker.io/kubevirt/cdi-uploadserver:v1.18.0', ' - name: UPLOAD_PROXY_IMAGE', ' value: docker.io/kubevirt/cdi-uploadproxy:v1.18.0', ' - name: VERBOSITY', ' value: \"1\"', ' - name: PULL_POLICY', ' value: IfNotPresent', ' image: docker.io/kubevirt/cdi-operator:v1.18.0', ' imagePullPolicy: IfNotPresent', ' name: cdi-operator', ' ports:', ' - containerPort: 60000', ' name: metrics', ' protocol: TCP', ' resources: {}', ' securityContext:', ' runAsNonRoot: true', ' serviceAccountName: cdi-operator', '---', 'apiVersion: apps/v1', 'kind: Deployment', 'metadata:', ' labels:', ' name: node-maintenance-operator', ' name: node-maintenance-operator', 'spec:', ' replicas: 1', ' selector:', ' matchLabels:', ' name: node-maintenance-operator', ' strategy: {}', ' template:', ' metadata:', ' labels:', ' name: node-maintenance-operator', ' spec:', ' affinity:', ' nodeAffinity:', ' requiredDuringSchedulingIgnoredDuringExecution:', ' nodeSelectorTerms:', ' - matchExpressions:', ' - key: node-role.kubernetes.io/master', ' operator: Exists', ' containers:', ' - env:', ' - name: WATCH_NAMESPACE', ' valueFrom:', ' fieldRef:', ' fieldPath: metadata.namespace', ' - name: POD_NAME', ' valueFrom:', ' fieldRef:', ' fieldPath: metadata.name', ' - name: OPERATOR_NAME', ' value: node-maintenance-operator', ' image: quay.io/kubevirt/node-maintenance-operator:v0.6.0', ' imagePullPolicy: Always', ' name: node-maintenance-operator', ' resources: {}', ' serviceAccountName: node-maintenance-operator', ' tolerations:', ' - effect: NoSchedule', ' key: node-role.kubernetes.io/master', '---', 'apiVersion: apps/v1', 'kind: Deployment', 'metadata:', ' labels:', ' name: hostpath-provisioner-operator', ' name: hostpath-provisioner-operator', 'spec:', ' replicas: 1', ' selector:', ' matchLabels:', ' name: hostpath-provisioner-operator', ' operator.hostpath-provisioner.kubevirt.io: \"\"', ' strategy: {}', ' template:', ' metadata:', ' labels:', ' name: hostpath-provisioner-operator', ' operator.hostpath-provisioner.kubevirt.io: \"\"', ' spec:', ' containers:', ' - env:', ' - name: WATCH_NAMESPACE', ' valueFrom:', ' fieldRef:', ' fieldPath: metadata.namespace', ' - name: POD_NAME', ' valueFrom:', ' fieldRef:', ' fieldPath: metadata.name', ' - name: OPERATOR_NAME', ' value: hostpath-provisioner-operator', ' - name: PROVISIONER_IMAGE', ' value: quay.io/kubevirt/hostpath-provisioner:v0.4.0', ' - name: PULL_POLICY', ' value: IfNotPresent', ' image: quay.io/kubevirt/hostpath-provisioner-operator:v0.4.3', ' imagePullPolicy: IfNotPresent', ' name: hostpath-provisioner-operator', ' resources: {}', ' serviceAccountName: hostpath-provisioner-operator', '---', 'apiVersion: apps/v1', 'kind: Deployment', 'metadata:', ' labels:', ' name: vm-import-operator', ' name: vm-import-operator', 'spec:', ' replicas: 1', ' selector:', ' matchLabels:', ' name: vm-import-operator', ' operator.v2v.kubevirt.io: \"\"', ' strategy: {}', ' template:', ' metadata:', ' labels:', ' name: vm-import-operator', ' operator.v2v.kubevirt.io: \"\"', ' spec:', ' containers:', ' - env:', ' - name: DEPLOY_CLUSTER_RESOURCES', ' value: \"true\"', ' - name: OPERATOR_VERSION', ' value: v0.0.2', ' - name: CONTROLLER_IMAGE', ' value: quay.io/kubevirt/vm-import-controller:v0.0.2', ' - name: PULL_POLICY', ' value: IfNotPresent', ' - name: WATCH_NAMESPACE', ' - name: POD_NAME', ' valueFrom:', ' fieldRef:', ' fieldPath: metadata.name', ' image: quay.io/kubevirt/vm-import-operator:v0.0.2', ' imagePullPolicy: IfNotPresent', ' name: vm-import-operator', ' resources: {}', ' securityContext:', ' runAsNonRoot: true', ' serviceAccountName: vm-import-operator', 'deployment.apps/hyperconverged-cluster-operator created', 'deployment.apps/cluster-network-addons-operator created', 'deployment.apps/virt-operator created', 'deployment.apps/kubevirt-ssp-operator created', 'deployment.apps/cdi-operator created', 'deployment.apps/node-maintenance-operator created', 'deployment.apps/hostpath-provisioner-operator created', 'deployment.apps/vm-import-operator created', '+ sleep 20', '+ kubectl wait deployment/hyperconverged-cluster-operator --for=condition=Available --timeout=1080s', 'deployment.apps/hyperconverged-cluster-operator condition met', '+ for op in cdi-operator cluster-network-addons-operator kubevirt-ssp-operator node-maintenance-operator vm-import-operator', '+ kubectl wait deployment/cdi-operator --for=condition=Available --timeout=540s', 'deployment.apps/cdi-operator condition met', '+ for op in cdi-operator cluster-network-addons-operator kubevirt-ssp-operator node-maintenance-operator vm-import-operator', '+ kubectl wait deployment/cluster-network-addons-operator --for=condition=Available --timeout=540s', 'deployment.apps/cluster-network-addons-operator condition met', '+ for op in cdi-operator cluster-network-addons-operator kubevirt-ssp-operator node-maintenance-operator vm-import-operator', '+ kubectl wait deployment/kubevirt-ssp-operator --for=condition=Available --timeout=540s', 'deployment.apps/kubevirt-ssp-operator condition met', '+ for op in cdi-operator cluster-network-addons-operator kubevirt-ssp-operator node-maintenance-operator vm-import-operator', '+ kubectl wait deployment/node-maintenance-operator --for=condition=Available --timeout=540s', 'deployment.apps/node-maintenance-operator condition met', '+ for op in cdi-operator cluster-network-addons-operator kubevirt-ssp-operator node-maintenance-operator vm-import-operator', '+ kubectl wait deployment/vm-import-operator --for=condition=Available --timeout=540s', 'deployment.apps/vm-import-operator condition met', '+ kubectl create -f _out/hco.cr.yaml', 'hyperconverged.hco.kubevirt.io/kubevirt-hyperconverged created', '+ sleep 10', '+ timeout 30m bash -c -- \\\\\\'until kubectl get -n kubevirt-hyperconverged hyperconvergeds kubevirt-hyperconverged -o go-template=\\\\\\'\\\\\\\\\\\\\\'\\\\\\'{{ range .status.conditions }}{{ if eq .type \"Available\" }}{{ .status }}{{ end }}{{ end }}\\\\\\'\\\\\\\\\\\\\\'\\\\\\' | grep True; do sleep 1; done\\\\\\'', 'True', '+ kubectl get -n kubevirt-hyperconverged hyperconvergeds kubevirt-hyperconverged -o \\\\\\'go-template={{ range .status.conditions }}{{ .type }}{{ \"\\\\\\\\t\" }}{{ .status }}{{ \"\\\\\\\\t\" }}{{ .message }}{{ \"\\\\', '\" }}{{ end }}\\\\\\'', 'ReconcileComplete\\\\tTrue\\\\tReconcile completed successfully', 'Available\\\\tTrue\\\\tReconcile completed successfully', 'Progressing\\\\tFalse\\\\tReconcile completed successfully', 'Degraded\\\\tFalse\\\\tReconcile completed successfully', 'Upgradeable\\\\tTrue\\\\tReconcile completed successfully', '+ for dep in cdi-apiserver cdi-deployment cdi-uploadproxy virt-api virt-controller', '+ kubectl wait deployment/cdi-apiserver --for=condition=Available --timeout=360s', 'deployment.apps/cdi-apiserver condition met', '+ for dep in cdi-apiserver cdi-deployment cdi-uploadproxy virt-api virt-controller', '+ kubectl wait deployment/cdi-deployment --for=condition=Available --timeout=360s', 'deployment.apps/cdi-deployment condition met', '+ for dep in cdi-apiserver cdi-deployment cdi-uploadproxy virt-api virt-controller', '+ kubectl wait deployment/cdi-uploadproxy --for=condition=Available --timeout=360s', 'deployment.apps/cdi-uploadproxy condition met', '+ for dep in cdi-apiserver cdi-deployment cdi-uploadproxy virt-api virt-controller', '+ kubectl wait deployment/virt-api --for=condition=Available --timeout=360s', 'deployment.apps/virt-api condition met', '+ for dep in cdi-apiserver cdi-deployment cdi-uploadproxy virt-api virt-controller', '+ kubectl wait deployment/virt-controller --for=condition=Available --timeout=360s', 'deployment.apps/virt-controller condition met', 'SUCCESS', \"+ \\\\'[\\\\' -z \\\\'\\\\' \\\\']\\\\'\", '+ echo SUCCESS', '+ exit 0', '+ status', '+ kubectl get hco -n kubevirt-hyperconverged -o yaml', 'apiVersion: v1', 'items:', '- apiVersion: hco.kubevirt.io/v1alpha1', ' kind: HyperConverged', ' metadata:', ' creationTimestamp: \"2020-09-26T22:56:57Z\"', ' finalizers:', ' - hyperconvergeds.hco.kubevirt.io', ' generation: 1', ' managedFields:', ' - apiVersion: hco.kubevirt.io/v1alpha1', ' fieldsType: FieldsV1', ' fieldsV1:', ' f:spec: {}', ' manager: kubectl', ' operation: Update', ' time: \"2020-09-26T22:56:57Z\"', ' - apiVersion: hco.kubevirt.io/v1alpha1', ' fieldsType: FieldsV1', ' fieldsV1:', ' f:metadata:', ' f:finalizers:', ' .: {}', ' v:\"hyperconvergeds.hco.kubevirt.io\": {}', ' f:status:', ' .: {}', ' f:conditions: {}', ' f:relatedObjects: {}', ' f:versions: {}', ' manager: hyperconverged-cluster-operator', ' operation: Update', ' time: \"2020-09-26T22:59:26Z\"', ' name: kubevirt-hyperconverged', ' namespace: kubevirt-hyperconverged', ' resourceVersion: \"26759\"', ' selfLink: /apis/hco.kubevirt.io/v1alpha1/namespaces/kubevirt-hyperconverged/hyperconvergeds/kubevirt-hyperconverged', ' uid: e2f29e5a-53b2-450e-8c76-656277cd887a', ' spec: {}', ' status:', ' conditions:', ' - lastHeartbeatTime: \"2020-09-26T22:59:26Z\"', ' lastTransitionTime: \"2020-09-26T22:56:58Z\"', ' message: Reconcile completed successfully', ' reason: ReconcileCompleted', ' status: \"True\"', ' type: ReconcileComplete', ' - lastHeartbeatTime: \"2020-09-26T22:59:26Z\"', ' lastTransitionTime: \"2020-09-26T22:59:26Z\"', ' message: Reconcile completed successfully', ' reason: ReconcileCompleted', ' status: \"True\"', ' type: Available', ' - lastHeartbeatTime: \"2020-09-26T22:59:26Z\"', ' lastTransitionTime: \"2020-09-26T22:59:26Z\"', ' message: Reconcile completed successfully', ' reason: ReconcileCompleted', ' status: \"False\"', ' type: Progressing', ' - lastHeartbeatTime: \"2020-09-26T22:59:26Z\"', ' lastTransitionTime: \"2020-09-26T22:58:11Z\"', ' message: Reconcile completed successfully', ' reason: ReconcileCompleted', ' status: \"False\"', ' type: Degraded', ' - lastHeartbeatTime: \"2020-09-26T22:59:26Z\"', ' lastTransitionTime: \"2020-09-26T22:59:26Z\"', ' message: Reconcile completed successfully', ' reason: ReconcileCompleted', ' status: \"True\"', ' type: Upgradeable', ' relatedObjects:', ' - apiVersion: scheduling.k8s.io/v1', ' kind: PriorityClass', ' name: kubevirt-cluster-critical', ' resourceVersion: \"23988\"', ' uid: bc0c51a9-81e3-4caa-8d00-b684c22012ba', ' - apiVersion: v1', ' kind: ConfigMap', ' name: kubevirt-config', ' namespace: kubevirt-hyperconverged', ' resourceVersion: \"23989\"', ' uid: 01231030-c0d7-4191-a19c-25ba0e8cc74e', ' - apiVersion: v1', ' kind: ConfigMap', ' name: kubevirt-storage-class-defaults', ' namespace: kubevirt-hyperconverged', ' resourceVersion: \"23990\"', ' uid: 37aae361-4d68-4629-9d53-7aabb218e263', ' - apiVersion: kubevirt.io/v1alpha3', ' kind: KubeVirt', ' name: kubevirt-kubevirt-hyperconverged', ' namespace: kubevirt-hyperconverged', ' resourceVersion: \"26756\"', ' uid: e852e27d-7c0f-4395-8c74-139e1280e401', ' - apiVersion: cdi.kubevirt.io/v1alpha1', ' kind: CDI', ' name: cdi-kubevirt-hyperconverged', ' resourceVersion: \"25550\"', ' uid: a3376ac7-d538-4b4a-b0da-1ab8eee40888', ' - apiVersion: networkaddonsoperator.network.kubevirt.io/v1alpha1', ' kind: NetworkAddonsConfig', ' name: cluster', ' resourceVersion: \"26566\"', ' uid: e4e358ab-3813-41fc-9dda-740470afd5d7', ' - apiVersion: ssp.kubevirt.io/v1', ' kind: KubevirtCommonTemplatesBundle', ' name: common-templates-kubevirt-hyperconverged', ' namespace: openshift', ' resourceVersion: \"26675\"', ' uid: 443fb1b8-fe95-4eb6-95d2-f4dacb1d1da8', ' - apiVersion: ssp.kubevirt.io/v1', ' kind: KubevirtNodeLabellerBundle', ' name: node-labeller-kubevirt-hyperconverged', ' namespace: kubevirt-hyperconverged', ' resourceVersion: \"25257\"', ' uid: 40479c0a-9f75-427d-864a-5778a95c5b36', ' - apiVersion: ssp.kubevirt.io/v1', ' kind: KubevirtTemplateValidator', ' name: template-validator-kubevirt-hyperconverged', ' namespace: kubevirt-hyperconverged', ' resourceVersion: \"25198\"', ' uid: d530b77f-8263-40e9-8c65-5b1935def74d', ' - apiVersion: ssp.kubevirt.io/v1', ' kind: KubevirtMetricsAggregation', ' name: metrics-aggregation-kubevirt-hyperconverged', ' namespace: kubevirt-hyperconverged', ' resourceVersion: \"24846\"', ' uid: 85399c1d-e618-4979-9831-107bbe88584c', ' - apiVersion: v1', ' kind: ConfigMap', ' name: v2v-vmware', ' namespace: kubevirt-hyperconverged', ' resourceVersion: \"23999\"', ' uid: 2d9695c3-4571-4529-a148-b91b9ec1b099', ' - apiVersion: v2v.kubevirt.io/v1alpha1', ' kind: VMImportConfig', ' name: vmimport-kubevirt-hyperconverged', ' resourceVersion: \"25761\"', ' uid: bebc5dde-e31e-40d7-b8a4-2af7858e1256', ' versions:', ' - name: operator', ' version: 1.1.0', 'kind: List', 'metadata:', ' resourceVersion: \"\"', ' selfLink: \"\"', '+ kubectl get pods -n kubevirt-hyperconverged', 'NAME READY STATUS RESTARTS AGE', 'bridge-marker-5cgj2 1/1 Running 0 2m41s', 'bridge-marker-6gxrq 1/1 Running 0 2m41s', 'bridge-marker-6l9lg 1/1 Running 0 2m41s', 'bridge-marker-6ttjz 1/1 Running 0 2m41s', 'bridge-marker-bn8vh 1/1 Running 0 2m41s', 'bridge-marker-gp95h 1/1 Running 0 2m41s', 'cdi-apiserver-66c5fb4595-jz8jz 1/1 Running 0 2m45s', 'cdi-deployment-7f6c498dcf-fk4ff 1/1 Running 0 2m46s', 'cdi-operator-748565fbd8-l7z5n 1/1 Running 0 3m12s', 'cdi-uploadproxy-748db7f7c4-kgtvl 1/1 Running 0 2m46s', 'cluster-network-addons-operator-85ff784c67-ml5d2 1/1 Running 0 3m12s', 'hostpath-provisioner-operator-6bbf5ffd9c-vx2k8 1/1 Running 0 3m11s', 'hyperconverged-cluster-operator-59fd8f5765-m5sgp 1/1 Running 0 3m12s', 'kube-cni-linux-bridge-plugin-46j5b 1/1 Running 0 2m41s', 'kube-cni-linux-bridge-plugin-4gmts 1/1 Running 0 2m41s', 'kube-cni-linux-bridge-plugin-96jpq 1/1 Running 0 2m41s', 'kube-cni-linux-bridge-plugin-vlgg2 1/1 Running 0 2m41s', 'kube-cni-linux-bridge-plugin-wjvvb 1/1 Running 0 2m41s', 'kube-cni-linux-bridge-plugin-wvj4q 1/1 Running 0 2m41s', 'kubemacpool-mac-controller-manager-76596b6f8f-njl5v 1/1 Running 0 2m42s', 'kubemacpool-mac-controller-manager-76596b6f8f-pqzvz 0/1 Running 0 2m42s', 'kubevirt-node-labeller-q2dhw 1/1 Running 0 2m4s', 'kubevirt-node-labeller-qpgj8 1/1 Running 0 2m4s', 'kubevirt-node-labeller-xsjz5 1/1 Running 0 2m4s', 'kubevirt-ssp-operator-55d9699848-hkn85 1/1 Running 0 3m12s', 'nmstate-handler-4qssj 1/1 Running 0 2m40s', 'nmstate-handler-kvwdl 1/1 Running 0 2m40s', 'nmstate-handler-l5dcp 1/1 Running 0 2m40s', 'nmstate-handler-s48bq 1/1 Running 0 2m40s', 'nmstate-handler-z54nk 1/1 Running 0 2m40s', 'nmstate-handler-zq9bl 1/1 Running 0 2m40s', 'node-maintenance-operator-68fb7b4889-dcfdn 1/1 Running 0 3m11s', 'ovs-cni-amd64-6rmvn 2/2 Running 0 2m40s', 'ovs-cni-amd64-8z6x2 2/2 Running 0 2m40s', 'ovs-cni-amd64-f5jw2 2/2 Running 0 2m40s', 'ovs-cni-amd64-f96kj 2/2 Running 0 2m40s', 'ovs-cni-amd64-rb8wd 2/2 Running 0 2m40s', 'ovs-cni-amd64-vn2xn 2/2 Running 0 2m40s', 'virt-api-7cf789bcb8-2b85v 1/1 Running 0 106s', 'virt-api-7cf789bcb8-dm4qg 1/1 Running 0 106s', 'virt-controller-7557668d6b-95kz4 1/1 Running 0 70s', 'virt-controller-7557668d6b-h2trd 1/1 Running 0 70s', 'virt-handler-495rk 1/1 Running 0 70s', 'virt-handler-6gptn 1/1 Running 0 70s', 'virt-handler-85wgv 1/1 Running 0 70s', 'virt-operator-6cbcb47b78-9v4tf 1/1 Running 0 2m30s', 'virt-operator-6cbcb47b78-bkvmj 1/1 Running 0 2m30s', 'virt-template-validator-b7bcb65d4-gpv92 0/1 CrashLoopBackOff 4 2m5s', 'virt-template-validator-b7bcb65d4-z2xct 0/1 CrashLoopBackOff 3 2m5s', 'vm-import-controller-6c64995476-vtcfb 1/1 Running 2 2m47s', 'vm-import-operator-6df99df7cd-9chmq 1/1 Running 0 3m11s', '+ kubectl get hco kubevirt-hyperconverged -n kubevirt-hyperconverged \\\\\\'-o=jsonpath={range .status.conditions[*]}{.type}{\"\\\\\\\\t\"}{.status}{\"\\\\\\\\t\"}{.message}{\"\\\\', '\"}{end}\\\\\\'', 'ReconcileComplete\\\\tTrue\\\\tReconcile completed successfully', 'Available\\\\tTrue\\\\tReconcile completed successfully', 'Progressing\\\\tFalse\\\\tReconcile completed successfully', 'Degraded\\\\tFalse\\\\tReconcile completed successfully', 'Upgradeable\\\\tTrue\\\\tReconcile completed successfully', \"++ kubectl get pods -n kubevirt-hyperconverged \\\\'--field-selector=status.phase!=Running\\\\' -o custom-columns=:metadata.name\", 'which: no docker in (/tmp/shared:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/go/bin:/go/bin)', 'eval ./hack/build-tests.sh', 'go: github.com/kubevirt/cluster-network-addons-operator@v0.3.1-0.20200527095331-9cc2867ac8dc requires', '\\\\tgithub.com/operator-framework/operator-sdk@v0.12.0 requires', '\\\\tgithub.com/operator-framework/operator-registry@v1.1.1 requires', '\\\\tbitbucket.org/ww/goautoneg@v0.0.0-20120707110453-75cd24fc2f2c: reading https://api.bitbucket.org/2.0/repositories/ww/goautoneg?fields=scm: 404 Not Found', 'make: *** [build-functest] Error 1', '2020/09/26 22:59:52 Container test in pod e2e-aws-cnv failed, exit code 2, reason Error', '2020/09/26 23:14:27 Copied 112.27MB of artifacts from e2e-aws-cnv to /logs/artifacts/e2e-aws', '2020/09/26 23:14:28 Releasing lease for \"aws-quota-slice\"', '2020/09/26 23:14:28 No custom metadata found and prow metadata already exists. Not updating the metadata.', '2020/09/26 23:14:28 Ran for 53m50s', 'error: some steps failed:', ' * could not run steps: step e2e-aws failed: template pod \"e2e-aws-cnv\" failed: the pod ci-op-xl3p51qp/e2e-aws-cnv failed after 52m26s (failed containers: test): ContainerFailed one or more containers exited', '', 'Container test exited with code 2, reason Error', '---', 'd6b-h2trd 1/1 Running 0 70s', 'virt-handler-495rk 1/1 Running 0 70s', 'virt-handler-6gptn 1/1 Running 0 70s', 'virt-handler-85wgv 1/1 Running 0 70s', 'virt-operator-6cbcb47b78-9v4tf 1/1 Running 0 2m30s', 'virt-operator-6cbcb47b78-bkvmj 1/1 Running 0 2m30s', 'virt-template-validator-b7bcb65d4-gpv92 0/1 CrashLoopBackOff 4 2m5s', 'virt-template-validator-b7bcb65d4-z2xct 0/1 CrashLoopBackOff 3 2m5s', 'vm-import-controller-6c64995476-vtcfb 1/1 Running 2 2m47s', 'vm-import-operator-6df99df7cd-9chmq 1/1 Running 0 3m11s', '+ kubectl get hco kubevirt-hyperconverged -n kubevirt-hyperconverged \\\\\\'-o=jsonpath={range .status.conditions[*]}{.type}{\"\\\\\\\\t\"}{.status}{\"\\\\\\\\t\"}{.message}{\"\\\\', '\"}{end}\\\\\\'', 'ReconcileComplete\\\\tTrue\\\\tReconcile completed successfully', 'Available\\\\tTrue\\\\tReconcile completed successfully', 'Progressing\\\\tFalse\\\\tReconcile completed successfully', 'Degraded\\\\tFalse\\\\tReconcile completed successfully', 'Upgradeable\\\\tTrue\\\\tReconcile completed successfully', \"++ kubectl get pods -n kubevirt-hyperconverged \\\\'--field-selector=status.phase!=Running\\\\' -o custom-columns=:metadata.name\", 'which: no docker in (/tmp/shared:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/go/bin:/go/bin)', 'eval ./hack/build-tests.sh', 'go: github.com/kubevirt/cluster-network-addons-operator@v0.3.1-0.20200527095331-9cc2867ac8dc requires', '\\\\tgithub.com/operator-framework/operator-sdk@v0.12.0 requires', '\\\\tgithub.com/operator-framework/operator-registry@v1.1.1 requires', '\\\\tbitbucket.org/ww/goautoneg@v0.0.0-20120707110453-75cd24fc2f2c: reading https://api.bitbucket.org/2.0/repositories/ww/goautoneg?fields=scm: 404 Not Found', 'make: *** [build-functest] Error 1', '---', '2020/09/26 23:14:28 could not load result reporting options: failed to read file \"\": open : no such file or directory', \"'\"]\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "yaYWmzJoL1NL", + "outputId": "19cba100-d575-47bd-800e-4a6ce69c9fd8" + }, + "source": [ + "#url core needed to pull\n", + "website2 = \"https://gcsweb-ci.apps.ci.l2s4.p1.openshiftapps.com\"\n", + "base2 = \"https://gcsweb-ci.apps.ci.l2s4.p1.openshiftapps.com/gcs/origin-ci-test/logs/release-openshift-ocp-installer-e2e-aws-serial-4.1/\"\n", + "ending2 = \"build-log.txt\"\n", + "page2 = requests.get(base2) \n", + "data2 = page2.text\n", + "soup2 = BeautifulSoup(data2)\n", + "links2 = []\n", + "for link2 in soup2.find_all('a'):\n", + " links2.append(link2.get('href'))\n", + "links2 = links2[1:-1]\n", + "\n", + "final_array2 = []\n", + "# create array of urls\n", + "for x in range(len(links2)):\n", + " final_array2.append(str(website2) + str(links2[x]) + str(ending2))\n", + "\n", + "\n", + "# pull all urls logs and store in 2-d array where array_of_logs[x] is a build-log file and \n", + "# array_of_logs[x][y] is an individual log line split by new line\n", + "array_of_logs2 = []\n", + "for x in range(len(final_array2)):\n", + " page2 = urlopen(final_array2[x])\n", + " html_bytes2 = page2.read()\n", + " array_of_logs2.append(str(html_bytes2).split('\\\\n'))\n", + " \n", + "# first log\n", + "print(array_of_logs2[0])\n", + "\n", + "\n", + "# Analysis on the log data. Trying to find a framework. API (Ningxiao, Parker, Tianze, Hong)\n", + "# Identify limitations with data and potential risks of achieving project goals.\n", + "\n", + "\n", + "# ******* Tianze *******\n", + "#ignore useless \"Waiting for setup to finish...\"\n", + "def ignoreWaiting(logs):\n", + " for i in range(len(logs)):\n", + " if \"Waiting for setup to finish...\" in logs[i]:\n", + " logs[i]=\"\"\n", + " return logs\n", + "# ******* Tianze *******\n" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "[\"b'2020/09/25 21:55:40 ci-operator version v20200924-c41f44a\", '2020/09/25 21:55:40 No source defined', '2020/09/25 21:55:40 Resolved release latest to registry.svc.ci.openshift.org/ocp/release:4.1', '2020/09/25 21:55:40 Using namespace https://console.svc.ci.openshift.org/k8s/cluster/projects/ci-op-kcf6vnx8', '2020/09/25 21:55:40 Running [release-inputs], [images], [release:latest], e2e-aws-serial', '2020/09/25 21:55:40 Creating namespace ci-op-kcf6vnx8', '2020/09/25 21:55:40 Setting up pipeline imagestream for the test', '2020/09/25 21:55:40 Created secret e2e-aws-serial-cluster-profile', '2020/09/25 21:55:40 Created secret pull-secret', '2020/09/25 21:55:40 Created PDB for pods with openshift.io/build.name label', '2020/09/25 21:55:40 Created PDB for pods with created-by-ci label', '2020/09/25 21:55:40 Tagged shared images from ocp/4.1:${component}, images will be pullable from registry.svc.ci.openshift.org/ci-op-kcf6vnx8/stable:${component}', '2020/09/25 21:55:42 Importing release image latest', '2020/09/25 21:56:48 Imported release 4.1.0-0.nightly-2020-07-29-210856 created at 2020-07-29 21:11:43 +0000 UTC with 84 images to tag release:latest', '2020/09/25 21:56:48 Acquiring lease for \"aws-quota-slice\"', '2020/09/25 21:56:48 Acquired lease \"c760a5ee-6cd8-45a1-bb8a-4002563fc9a8\" for \"aws-quota-slice\"', '2020/09/25 21:56:48 Executing template e2e-aws-serial', '2020/09/25 21:56:48 Creating or restarting template instance', '2020/09/25 21:56:48 Template instance e2e-aws-serial already deleted, do not need to wait any longer', '2020/09/25 21:56:48 Waiting for template instance to be ready', '2020/09/25 21:56:50 Running pod e2e-aws-serial', '2020/09/25 22:31:04 Container setup in pod e2e-aws-serial completed successfully', '2020/09/25 23:59:33 Copied 122.58MB of artifacts from e2e-aws-serial to /logs/artifacts/e2e-aws-serial', '2020/09/25 23:59:33 Releasing lease for \"aws-quota-slice\"', '2020/09/25 23:59:33 No custom metadata found and prow metadata already exists. Not updating the metadata.', '2020/09/25 23:59:34 Ran for 2h3m53s', '2020/09/25 23:59:34 could not load result reporting options: failed to read file \"\": open : no such file or directory', \"'\"]\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "aRyol0yU4HP_", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 232 + }, + "outputId": "2622a09d-6a9c-4a36-e2ef-f8d95ee07c83" + }, + "source": [ + "# ******* PARKER *******\n", + "# helper function detecting if a string is a date / timestamp\n", + "def is_date(str):\n", + " try:\n", + " dateutil.parser.parse(str)\n", + " return True\n", + " except:\n", + " return False\n", + "\n", + "# logs variable contains all parsed logs\n", + "logs = []\n", + "for i in range(len(array_of_logs2)):\n", + " # removing newline characters\n", + " array_of_logs2[i] = str(array_of_logs[i]).splitlines()\n", + " array_of_logs2[i] = str(array_of_logs[i]).replace('\\\\n', ' ')\n", + " \n", + "\n", + "# removes leading 'b from log\n", + " array_of_logs2[i] = array_of_logs[i][0][2:]\n", + "# splitting each section as its own index (for parsing)\n", + " array_of_logs2[i] = str(array_of_logs[i]).split(' ')\n", + "\n", + "# tmp is log without timestamps\n", + " tmp = []\n", + " for j in range(len(array_of_logs2[i])):\n", + " if is_date(array_of_logs2[i][j]) == False:\n", + " tmp.append(array_of_logs2[i][j])\n", + " else:\n", + " continue\n", + " logs.append(tmp)\n", + "\n", + "# removes whitespace characters and keeps root words\n", + "stemmer = SnowballStemmer(\"english\")\n", + "for log in logs:\n", + " log[:] = [stemmer.stem(x) for x in log if x != '']" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "error", + "ename": "IndexError", + "evalue": "ignored", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mIndexError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 12\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mi\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0marray_of_logs2\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m-\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 13\u001b[0m \u001b[0;31m# removing newline characters\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 14\u001b[0;31m \u001b[0marray_of_logs2\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mi\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mstr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0marray_of_logs\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mi\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msplitlines\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 15\u001b[0m \u001b[0marray_of_logs2\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mi\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mstr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0marray_of_logs\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mi\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mreplace\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'\\\\n'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m' '\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 16\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mIndexError\u001b[0m: list index out of range" + ] + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "WtFxnlMOmp3W", + "colab": { + "base_uri": "https://localhost:8080/" + }, + "outputId": "f2995c42-34b9-436d-87e7-6f5eea86c085" + }, + "source": [ + "import drain3\n", + "from drain3 import TemplateMiner\n", + "import json\n", + "import logging\n", + "import sys\n", + "from drain3.kafka_persistence import KafkaPersistence\n", + "\n", + "template_miner = TemplateMiner(None)\n", + "i = 0\n", + "array_of_logs2 = array_of_logs2[:100]\n", + "while True:\n", + " if i >= len(array_of_logs2):\n", + " break\n", + " log_line = ' '.join(array_of_logs2[i])\n", + " i += 1\n", + " if log_line == 'q':\n", + " break\n", + " result = template_miner.add_log_message(log_line)\n", + " result_json = json.dumps(result)\n", + " print(result_json)\n", + "\n", + "print(\"Clusters:\")\n", + "for cluster in template_miner.drain.clusters:\n", + " print(cluster)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "config file not found: drain3.ini\n", + "IOPub data rate exceeded.\n", + "The notebook server will temporarily stop sending output\n", + "to the client in order to avoid crashing it.\n", + "To change this limit, set the config variable\n", + "`--NotebookApp.iopub_data_rate_limit`.\n", + "\n", + "Current values:\n", + "NotebookApp.iopub_data_rate_limit=1000000.0 (bytes/sec)\n", + "NotebookApp.rate_limit_window=3.0 (secs)\n", + "\n" + ], + "name": "stderr" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "9RPAVaF3LoRb", + "outputId": "a2e91809-f2d1-4783-ca20-28b737a58e7e" + }, + "source": [ + "!pip3 install drain3\n", + "!pip3 install kafka-python\n", + "!pip3 install redis" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Collecting drain3\n", + " Downloading https://files.pythonhosted.org/packages/03/df/cd2118d85b0401cd4b2cc555b97cd5a918ca551a035c77c853087321328e/drain3-0.9.3.tar.gz\n", + "Collecting jsonpickle==1.5.1\n", + " Downloading https://files.pythonhosted.org/packages/77/a7/c2f527ddce3155ae9e008385963c2325cbfd52969f8b38efa2723e2af4af/jsonpickle-1.5.1-py2.py3-none-any.whl\n", + "Requirement already satisfied: cachetools==4.2.1 in /usr/local/lib/python3.7/dist-packages (from drain3) (4.2.1)\n", + "Requirement already satisfied: importlib-metadata; python_version < \"3.8\" in /usr/local/lib/python3.7/dist-packages (from jsonpickle==1.5.1->drain3) (3.7.2)\n", + "Requirement already satisfied: typing-extensions>=3.6.4; python_version < \"3.8\" in /usr/local/lib/python3.7/dist-packages (from importlib-metadata; python_version < \"3.8\"->jsonpickle==1.5.1->drain3) (3.7.4.3)\n", + "Requirement already satisfied: zipp>=0.5 in /usr/local/lib/python3.7/dist-packages (from importlib-metadata; python_version < \"3.8\"->jsonpickle==1.5.1->drain3) (3.4.1)\n", + "Building wheels for collected packages: drain3\n", + " Building wheel for drain3 (setup.py) ... \u001b[?25l\u001b[?25hdone\n", + " Created wheel for drain3: filename=drain3-0.9.3-cp37-none-any.whl size=16397 sha256=40988bb8854eee8fd03684b245da3c216327103c61103c854093aed2ee220185\n", + " Stored in directory: /root/.cache/pip/wheels/44/eb/c8/0c42c729fa7f47040d8b9bc2e8359a96fee8a4b2bf442fd924\n", + "Successfully built drain3\n", + "Installing collected packages: jsonpickle, drain3\n", + "Successfully installed drain3-0.9.3 jsonpickle-1.5.1\n", + "Collecting kafka-python\n", + "\u001b[?25l Downloading https://files.pythonhosted.org/packages/75/68/dcb0db055309f680ab2931a3eeb22d865604b638acf8c914bedf4c1a0c8c/kafka_python-2.0.2-py2.py3-none-any.whl (246kB)\n", + "\u001b[K |████████████████████████████████| 256kB 6.8MB/s \n", + "\u001b[?25hInstalling collected packages: kafka-python\n", + "Successfully installed kafka-python-2.0.2\n", + "Collecting redis\n", + "\u001b[?25l Downloading https://files.pythonhosted.org/packages/a7/7c/24fb0511df653cf1a5d938d8f5d19802a88cef255706fdda242ff97e91b7/redis-3.5.3-py2.py3-none-any.whl (72kB)\n", + "\u001b[K |████████████████████████████████| 81kB 4.3MB/s \n", + "\u001b[?25hInstalling collected packages: redis\n", + "Successfully installed redis-3.5.3\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "DtfC_gaeGv8v" + }, + "source": [ + "The cell below runs the drain3 program. Process the log info and generate clusters and a prefix tree of the log information." + ] + }, + { + "cell_type": "code", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "cb0-1Ou6EYbx", + "outputId": "862d6ecb-3a43-48d7-f053-6ae66bb2c3ee" + }, + "source": [ + "import subprocess\n", + "import time\n", + "\n", + "logger = logging.getLogger(__name__)\n", + "logging.basicConfig(stream=sys.stdout, level=logging.INFO, format='%(message)s')\n", + "\n", + "template_miner = TemplateMiner()\n", + "\n", + "line_count = 0\n", + "start_time = time.time()\n", + "batch_start_time = start_time\n", + "batch_size = 10000\n", + "for i in range(len(array_of_logs2)):\n", + " for line in array_of_logs2[i]:\n", + " line = line.rstrip()\n", + " line = line.partition(\": \")[2]\n", + " result = template_miner.add_log_message(line)\n", + " line_count += 1\n", + " if line_count % batch_size == 0:\n", + " time_took = time.time() - batch_start_time\n", + " rate = batch_size / time_took\n", + " logger.info(f\"Processing line: {line_count}, rate {rate:.1f} lines/sec, \"\n", + " f\"{len(template_miner.drain.clusters)} clusters so far.\")\n", + " batch_start_time = time.time()\n", + " if result[\"change_type\"] != \"none\":\n", + " result_json = json.dumps(result)\n", + " logger.info(f\"Input ({line_count}): \" + line)\n", + " logger.info(\"Result: \" + result_json)\n", + "\n", + "time_took = time.time() - start_time\n", + "rate = line_count / time_took\n", + "logger.info(f\"--- Done processing file. Total of {line_count} lines, rate {rate:.1f} lines/sec, \"\n", + " f\"{len(template_miner.drain.clusters)} clusters\")\n", + "sorted_clusters = sorted(template_miner.drain.clusters, key=lambda it: it.size, reverse=True)\n", + "for cluster in sorted_clusters:\n", + " logger.info(cluster)\n", + "\n", + "print(\"Prefix Tree:\")\n", + "template_miner.drain.print_tree()\n", + "\n", + "template_miner.profiler.report(0)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Starting Drain3 template miner\n", + "Loading configuration from drain3.ini\n", + "config file not found: drain3.ini\n", + "Input (1): \n", + "Result: {\"change_type\": \"cluster_created\", \"cluster_id\": 1, \"cluster_size\": 1, \"template_mined\": \"\", \"cluster_count\": 1}\n", + "Processing line: 10000, rate 118121.1 lines/sec, 1 clusters so far.\n", + "Processing line: 20000, rate 128148.2 lines/sec, 1 clusters so far.\n", + "Processing line: 30000, rate 144391.2 lines/sec, 1 clusters so far.\n", + "Processing line: 40000, rate 138624.0 lines/sec, 1 clusters so far.\n", + "Processing line: 50000, rate 135807.4 lines/sec, 1 clusters so far.\n", + "Processing line: 60000, rate 134098.0 lines/sec, 1 clusters so far.\n", + "Processing line: 70000, rate 135249.5 lines/sec, 1 clusters so far.\n", + "Processing line: 80000, rate 129770.2 lines/sec, 1 clusters so far.\n", + "Processing line: 90000, rate 134272.3 lines/sec, 1 clusters so far.\n", + "Processing line: 100000, rate 140000.5 lines/sec, 1 clusters so far.\n", + "Processing line: 110000, rate 132182.7 lines/sec, 1 clusters so far.\n", + "Processing line: 120000, rate 121581.1 lines/sec, 1 clusters so far.\n", + "Processing line: 130000, rate 135760.4 lines/sec, 1 clusters so far.\n", + "Processing line: 140000, rate 146449.7 lines/sec, 1 clusters so far.\n", + "Processing line: 150000, rate 131333.8 lines/sec, 1 clusters so far.\n", + "Processing line: 160000, rate 136841.1 lines/sec, 1 clusters so far.\n", + "Processing line: 170000, rate 141831.2 lines/sec, 1 clusters so far.\n", + "Processing line: 180000, rate 135012.7 lines/sec, 1 clusters so far.\n", + "Processing line: 190000, rate 134598.9 lines/sec, 1 clusters so far.\n", + "Processing line: 200000, rate 139246.6 lines/sec, 1 clusters so far.\n", + "Processing line: 210000, rate 143068.3 lines/sec, 1 clusters so far.\n", + "Processing line: 220000, rate 136838.9 lines/sec, 1 clusters so far.\n", + "Processing line: 230000, rate 128096.9 lines/sec, 1 clusters so far.\n", + "Processing line: 240000, rate 130335.2 lines/sec, 1 clusters so far.\n", + "Processing line: 250000, rate 136070.5 lines/sec, 1 clusters so far.\n", + "Processing line: 260000, rate 137761.2 lines/sec, 1 clusters so far.\n", + "Processing line: 270000, rate 149725.5 lines/sec, 1 clusters so far.\n", + "Processing line: 280000, rate 135413.3 lines/sec, 1 clusters so far.\n", + "Processing line: 290000, rate 145574.4 lines/sec, 1 clusters so far.\n", + "Processing line: 300000, rate 136784.0 lines/sec, 1 clusters so far.\n", + "Processing line: 310000, rate 135356.5 lines/sec, 1 clusters so far.\n", + "Processing line: 320000, rate 126879.8 lines/sec, 1 clusters so far.\n", + "Processing line: 330000, rate 133886.1 lines/sec, 1 clusters so far.\n", + "Processing line: 340000, rate 135834.7 lines/sec, 1 clusters so far.\n", + "Processing line: 350000, rate 135627.4 lines/sec, 1 clusters so far.\n", + "Processing line: 360000, rate 140495.8 lines/sec, 1 clusters so far.\n", + "Processing line: 370000, rate 141877.3 lines/sec, 1 clusters so far.\n", + "Processing line: 380000, rate 140146.5 lines/sec, 1 clusters so far.\n", + "Processing line: 390000, rate 134580.3 lines/sec, 1 clusters so far.\n", + "Processing line: 400000, rate 137391.1 lines/sec, 1 clusters so far.\n", + "Processing line: 410000, rate 128744.9 lines/sec, 1 clusters so far.\n", + "Processing line: 420000, rate 130143.1 lines/sec, 1 clusters so far.\n", + "Processing line: 430000, rate 141732.0 lines/sec, 1 clusters so far.\n", + "Processing line: 440000, rate 136977.4 lines/sec, 1 clusters so far.\n", + "Processing line: 450000, rate 139593.8 lines/sec, 1 clusters so far.\n", + "Processing line: 460000, rate 144790.4 lines/sec, 1 clusters so far.\n", + "Processing line: 470000, rate 137773.4 lines/sec, 1 clusters so far.\n", + "Processing line: 480000, rate 134854.2 lines/sec, 1 clusters so far.\n", + "Processing line: 490000, rate 131235.6 lines/sec, 1 clusters so far.\n", + "Processing line: 500000, rate 130277.3 lines/sec, 1 clusters so far.\n", + "Processing line: 510000, rate 137528.5 lines/sec, 1 clusters so far.\n", + "Processing line: 520000, rate 147393.0 lines/sec, 1 clusters so far.\n", + "Processing line: 530000, rate 130455.2 lines/sec, 1 clusters so far.\n", + "Processing line: 540000, rate 137564.2 lines/sec, 1 clusters so far.\n", + "Processing line: 550000, rate 145514.8 lines/sec, 1 clusters so far.\n", + "Processing line: 560000, rate 138612.5 lines/sec, 1 clusters so far.\n", + "Processing line: 570000, rate 139010.4 lines/sec, 1 clusters so far.\n", + "Processing line: 580000, rate 136523.6 lines/sec, 1 clusters so far.\n", + "Processing line: 590000, rate 121904.8 lines/sec, 1 clusters so far.\n", + "Processing line: 600000, rate 133738.0 lines/sec, 1 clusters so far.\n", + "Processing line: 610000, rate 137351.1 lines/sec, 1 clusters so far.\n", + "Processing line: 620000, rate 139653.3 lines/sec, 1 clusters so far.\n", + "Processing line: 630000, rate 126251.6 lines/sec, 1 clusters so far.\n", + "Processing line: 640000, rate 143255.9 lines/sec, 1 clusters so far.\n", + "Processing line: 650000, rate 147238.8 lines/sec, 1 clusters so far.\n", + "Processing line: 660000, rate 126915.9 lines/sec, 1 clusters so far.\n", + "Processing line: 670000, rate 135129.7 lines/sec, 1 clusters so far.\n", + "Processing line: 680000, rate 129566.6 lines/sec, 1 clusters so far.\n", + "Processing line: 690000, rate 135591.9 lines/sec, 1 clusters so far.\n", + "Processing line: 700000, rate 147134.0 lines/sec, 1 clusters so far.\n", + "Processing line: 710000, rate 136911.7 lines/sec, 1 clusters so far.\n", + "Processing line: 720000, rate 133970.4 lines/sec, 1 clusters so far.\n", + "Processing line: 730000, rate 135731.4 lines/sec, 1 clusters so far.\n", + "Processing line: 740000, rate 147852.3 lines/sec, 1 clusters so far.\n", + "Processing line: 750000, rate 142273.8 lines/sec, 1 clusters so far.\n", + "Processing line: 760000, rate 138137.3 lines/sec, 1 clusters so far.\n", + "Processing line: 770000, rate 131218.8 lines/sec, 1 clusters so far.\n", + "Processing line: 780000, rate 111157.4 lines/sec, 1 clusters so far.\n", + "Processing line: 790000, rate 150556.3 lines/sec, 1 clusters so far.\n", + "Processing line: 800000, rate 127328.9 lines/sec, 1 clusters so far.\n", + "Processing line: 810000, rate 139929.1 lines/sec, 1 clusters so far.\n", + "Processing line: 820000, rate 137494.7 lines/sec, 1 clusters so far.\n", + "Processing line: 830000, rate 147884.1 lines/sec, 1 clusters so far.\n", + "Processing line: 840000, rate 144005.0 lines/sec, 1 clusters so far.\n", + "Processing line: 850000, rate 128560.3 lines/sec, 1 clusters so far.\n", + "Processing line: 860000, rate 131156.4 lines/sec, 1 clusters so far.\n", + "Processing line: 870000, rate 139360.9 lines/sec, 1 clusters so far.\n", + "Processing line: 880000, rate 138659.7 lines/sec, 1 clusters so far.\n", + "Processing line: 890000, rate 145846.2 lines/sec, 1 clusters so far.\n", + "Processing line: 900000, rate 139418.8 lines/sec, 1 clusters so far.\n", + "Processing line: 910000, rate 138572.2 lines/sec, 1 clusters so far.\n", + "Processing line: 920000, rate 136414.8 lines/sec, 1 clusters so far.\n", + "Processing line: 930000, rate 138172.3 lines/sec, 1 clusters so far.\n", + "Processing line: 940000, rate 117203.5 lines/sec, 1 clusters so far.\n", + "Processing line: 950000, rate 139526.9 lines/sec, 1 clusters so far.\n", + "Processing line: 960000, rate 138495.4 lines/sec, 1 clusters so far.\n", + "Processing line: 970000, rate 140319.5 lines/sec, 1 clusters so far.\n", + "Processing line: 980000, rate 142715.8 lines/sec, 1 clusters so far.\n", + "Processing line: 990000, rate 143049.2 lines/sec, 1 clusters so far.\n", + "Processing line: 1000000, rate 155242.2 lines/sec, 1 clusters so far.\n", + "Processing line: 1010000, rate 130838.1 lines/sec, 1 clusters so far.\n", + "Processing line: 1020000, rate 132089.1 lines/sec, 1 clusters so far.\n", + "Processing line: 1030000, rate 141162.5 lines/sec, 1 clusters so far.\n", + "Processing line: 1040000, rate 142479.2 lines/sec, 1 clusters so far.\n", + "Processing line: 1050000, rate 150973.1 lines/sec, 1 clusters so far.\n", + "Processing line: 1060000, rate 142660.0 lines/sec, 1 clusters so far.\n", + "Processing line: 1070000, rate 144624.2 lines/sec, 1 clusters so far.\n", + "Processing line: 1080000, rate 132861.9 lines/sec, 1 clusters so far.\n", + "Processing line: 1090000, rate 142139.8 lines/sec, 1 clusters so far.\n", + "Input (1098448): us-east-1 (zones: us-east-1b us-east-1c)\n", + "Result: {\"change_type\": \"cluster_created\", \"cluster_id\": 2, \"cluster_size\": 1, \"template_mined\": \"us-east-1 (zones: us-east-1b us-east-1c)\", \"cluster_count\": 2}\n", + "Input (1098457): Error applying plan:\"\n", + "Result: {\"change_type\": \"cluster_created\", \"cluster_id\": 3, \"cluster_size\": 1, \"template_mined\": \"Error applying plan:\\\"\", \"cluster_count\": 3}\n", + "Input (1098460): 1 error occurred:\"\n", + "Result: {\"change_type\": \"cluster_created\", \"cluster_id\": 4, \"cluster_size\": 1, \"template_mined\": \"1 error occurred:\\\"\", \"cluster_count\": 4}\n", + "Input (1098461): [ERR]: Error building changeset: timeout while waiting for state to become \\'accepted\\' (timeout: 5m0s)\"\n", + "Result: {\"change_type\": \"cluster_created\", \"cluster_id\": 5, \"cluster_size\": 1, \"template_mined\": \"[ERR]: Error building changeset: timeout while waiting for state to become \\\\'accepted\\\\' (timeout: 5m0s)\\\"\", \"cluster_count\": 5}\n", + "Input (1098473): failed to generate asset \\\\\"Cluster\\\\\": failed to create cluster: failed to apply using Terraform\"\n", + "Result: {\"change_type\": \"cluster_created\", \"cluster_id\": 6, \"cluster_size\": 1, \"template_mined\": \"failed to generate asset \\\\\\\\\\\"Cluster\\\\\\\\\\\": failed to create cluster: failed to apply using Terraform\\\"\", \"cluster_count\": 6}\n", + "Input (1098480): some steps failed:\n", + "Result: {\"change_type\": \"cluster_created\", \"cluster_id\": 7, \"cluster_size\": 1, \"template_mined\": \"some steps failed:\", \"cluster_count\": 7}\n", + "Input (1098481): step e2e-aws-serial failed: template pod \"e2e-aws-serial\" failed: the pod ci-op-6jxq6mqt/e2e-aws-serial failed after 18m49s (failed containers: setup): ContainerFailed one or more containers exited\n", + "Result: {\"change_type\": \"cluster_created\", \"cluster_id\": 8, \"cluster_size\": 1, \"template_mined\": \"step e2e-aws-serial failed: template pod \\\"e2e-aws-serial\\\" failed: the pod ci-op-6jxq6mqt/e2e-aws-serial failed after 18m49s (failed containers: setup): ContainerFailed one or more containers exited\", \"cluster_count\": 8}\n", + "Input (1098600): [us-west-1--26]\n", + "Result: {\"change_type\": \"cluster_created\", \"cluster_id\": 9, \"cluster_size\": 1, \"template_mined\": \"[us-west-1--26]\", \"cluster_count\": 9}\n", + "Input (1098606): Failed to patch the ci-op-n2904x8n namespace to update the ci.openshift.io/active annotation: namespaces \"ci-op-n2904x8n\" is forbidden: User \"system:serviceaccount:ci:ci-operator\" cannot patch namespaces in the namespace \"ci-op-n2904x8n\": no RBAC policy matched\n", + "Result: {\"change_type\": \"cluster_created\", \"cluster_id\": 10, \"cluster_size\": 1, \"template_mined\": \"Failed to patch the ci-op-n2904x8n namespace to update the ci.openshift.io/active annotation: namespaces \\\"ci-op-n2904x8n\\\" is forbidden: User \\\"system:serviceaccount:ci:ci-operator\\\" cannot patch namespaces in the namespace \\\"ci-op-n2904x8n\\\": no RBAC policy matched\", \"cluster_count\": 10}\n", + "Input (1098613): us-west-1--26\n", + "Result: {\"change_type\": \"cluster_created\", \"cluster_id\": 11, \"cluster_size\": 1, \"template_mined\": \"us-west-1--26\", \"cluster_count\": 11}\n", + "--- Done processing file. Total of 1098616 lines, rate 133104.5 lines/sec, 11 clusters\n", + "ID=1 : size=1098601 : \n", + "ID=2 : size=2 : us-east-1 (zones: us-east-1b us-east-1c)\n", + "ID=3 : size=2 : Error applying plan:\"\n", + "ID=4 : size=2 : 1 error occurred:\"\n", + "ID=5 : size=2 : [ERR]: Error building changeset: timeout while waiting for state to become \\'accepted\\' (timeout: 5m0s)\"\n", + "ID=6 : size=2 : failed to generate asset \\\\\"Cluster\\\\\": failed to create cluster: failed to apply using Terraform\"\n", + "ID=7 : size=1 : some steps failed:\n", + "ID=8 : size=1 : step e2e-aws-serial failed: template pod \"e2e-aws-serial\" failed: the pod ci-op-6jxq6mqt/e2e-aws-serial failed after 18m49s (failed containers: setup): ContainerFailed one or more containers exited\n", + "ID=9 : size=1 : [us-west-1--26]\n", + "ID=10 : size=1 : Failed to patch the ci-op-n2904x8n namespace to update the ci.openshift.io/active annotation: namespaces \"ci-op-n2904x8n\" is forbidden: User \"system:serviceaccount:ci:ci-operator\" cannot patch namespaces in the namespace \"ci-op-n2904x8n\": no RBAC policy matched\n", + "ID=11 : size=1 : us-west-1--26\n", + "Prefix Tree:\n", + "\n", + "\t<0>\n", + "\t<4>\n", + "\t\t<*>\n", + "\t<3>\n", + "\t\tError\n", + "\t\t<*>\n", + "\t\tsome\n", + "\t<14>\n", + "\t\t[ERR]:\n", + "\t\tfailed\n", + "\t<22>\n", + "\t\tstep\n", + "\t<1>\n", + "\t<28>\n", + "\t\tFailed\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "P2QaVqCj4NIF" + }, + "source": [ + "This cell removes dates and timestamps, whitespace and keeps the stems of words\n", + "\n", + "> Indented block\n", + "\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "yGDZGWSf32JQ" + }, + "source": [ + "# ******* PARKER *******\n", + "failures = []\n", + "successes = []\n", + "# word order for matrix: 0: fail, 1: error, 2: success, 3: run, 4: crashloopbackoff\n", + "word_matrix = []\n", + "for log in logs:\n", + " tmp = ' '.join(log)\n", + " tmp = TextBlob(tmp)\n", + " fail = tmp.word_counts['fail']\n", + " error = tmp.word_counts['error']\n", + " success = tmp.word_counts['success']\n", + " run = tmp.word_counts['run']\n", + " crash = tmp.word_counts['crashloopbackoff']\n", + " word_matrix.append([fail, error, success, run, crash])\n", + "\n", + "# remove noise\n", + "word_matrix = word_matrix[2:]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kHllUg9vwX_H" + }, + "source": [ + "This cell creates a matrix of keywords. each row is a single log entry and each column is a specific keyword" + ] + }, + { + "cell_type": "code", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "Xrj2maH9wVJl", + "outputId": "d2d03a5a-9cc5-44c6-b0f7-ee5bb0dd25e1" + }, + "source": [ + "# ******* PARKER *******\n", + "import math\n", + "# Latent Semantic Analysis approach\n", + "\n", + "num_of_docs = [0 for i in range(len(word_matrix[0]))]\n", + "for i in range(len(word_matrix)):\n", + " for j in range(len(word_matrix[i])):\n", + " if word_matrix[i][j] != 0:\n", + " num_of_docs[j] += 1\n", + "for i in range(len(word_matrix)):\n", + " for j in range(len(word_matrix[i])):\n", + " tf = word_matrix[i][j]\n", + " idf = math.log(len(word_matrix) / num_of_docs[j])\n", + " word_matrix[i][j] = tf * idf\n", + "\n", + "# TODO: try to implement anomaly detection with word matrix" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "[[0.023530497410194036, 0.0, 0.05848019881595618, 0.0, 0.0], [0.023530497410194036, 0.0, 0.05848019881595618, 0.0, 0.0], [0.023530497410194036, 0.0, 0.05848019881595618, 0.0, 0.0], [0.023530497410194036, 0.0, 0.05848019881595618, 0.0, 0.0], [0.023530497410194036, 0.0, 0.05848019881595618, 0.0, 0.0], [0.21177447669174632, 0.41928699106748313, 0.023392079526382472, 0.0, 0.0], [0.07059149223058211, 0.29949070790534504, 0.2924009940797809, 0.0, 1.5756171428283539], [0.07059149223058211, 0.5390832742296211, 0.2924009940797809, 0.0, 0.0], [0.07059149223058211, 0.4791851326485521, 0.30409703384297215, 0.0, 0.39390428570708846], [0.07059149223058211, 0.4791851326485521, 0.30409703384297215, 0.0, 0.39390428570708846], [0.07059149223058211, 0.29949070790534504, 0.2924009940797809, 0.0, 1.5756171428283539], [0.0, 0.059898141581069014, 0.0, 0.0, 0.0], [0.04706099482038807, 0.29949070790534504, 0.2924009940797809, 0.0, 1.5756171428283539], [0.04706099482038807, 0.29949070790534504, 0.2924009940797809, 0.0, 1.5756171428283539], [0.04706099482038807, 0.5390832742296211, 0.3157930736061634, 0.0, 0.0], [0.04706099482038807, 0.29949070790534504, 0.2924009940797809, 0.0, 1.5756171428283539], [0.07059149223058211, 0.29949070790534504, 0.1286564373951036, 0.0, 2.363425714242531], [0.04706099482038807, 0.5390832742296211, 0.3157930736061634, 0.0, 0.0], [0.04706099482038807, 0.29949070790534504, 0.2924009940797809, 0.0, 1.5756171428283539], [0.04706099482038807, 0.41928699106748313, 0.2924009940797809, 0.0, 0.7878085714141769], [0.04706099482038807, 0.41928699106748313, 0.3157930736061634, 0.0, 0.7878085714141769], [0.04706099482038807, 0.29949070790534504, 0.1286564373951036, 0.0, 2.363425714242531], [0.04706099482038807, 0.4791851326485521, 0.3157930736061634, 0.0, 0.39390428570708846], [0.04706099482038807, 0.4791851326485521, 0.37427327242211955, 0.0, 0.39390428570708846], [0.04706099482038807, 0.6588795573917592, 0.4093613917116933, 0.0, 0.0], [0.04706099482038807, 0.4791851326485521, 0.3157930736061634, 0.0, 0.39390428570708846], [0.04706099482038807, 0.4791851326485521, 0.3157930736061634, 0.0, 0.39390428570708846], [0.04706099482038807, 0.29949070790534504, 0.2924009940797809, 0.0, 1.5756171428283539], [0.04706099482038807, 0.41928699106748313, 0.3157930736061634, 0.0, 0.7878085714141769], [0.04706099482038807, 0.5989814158106901, 0.4210574314748845, 0.0, 0.39390428570708846], [0.04706099482038807, 0.29949070790534504, 0.1286564373951036, 0.0, 2.363425714242531], [0.04706099482038807, 0.4791851326485521, 0.3157930736061634, 0.0, 0.39390428570708846], [0.04706099482038807, 0.29949070790534504, 0.2924009940797809, 0.0, 1.5756171428283539], [0.04706099482038807, 0.4791851326485521, 0.3157930736061634, 0.0, 0.39390428570708846], [0.04706099482038807, 0.29949070790534504, 0.2924009940797809, 0.0, 1.5756171428283539], [0.04706099482038807, 0.5390832742296211, 0.3508811928957371, 0.0, 0.39390428570708846], [0.04706099482038807, 0.29949070790534504, 0.2924009940797809, 0.0, 1.5756171428283539], [0.04706099482038807, 0.29949070790534504, 0.1286564373951036, 0.0, 2.363425714242531], [0.0, 0.4791851326485521, 0.4795376302908407, 0.0, 0.0], [0.04706099482038807, 0.5390832742296211, 0.05848019881595618, 0.0, 0.0], [0.8470979067669853, 1.8568423890131394, 0.198832675974251, 0.0, 2.363425714242531], [0.04706099482038807, 0.29949070790534504, 0.3157930736061634, 0.0, 1.5756171428283539], [3.0119036685048366, 6.289304866012246, 2.818745582929088, 0.0, 0.0], [0.04706099482038807, 0.29949070790534504, 0.2924009940797809, 0.0, 1.5756171428283539], [0.04706099482038807, 0.41928699106748313, 0.2924009940797809, 0.0, 0.7878085714141769], [0.04706099482038807, 0.29949070790534504, 0.2924009940797809, 0.0, 1.5756171428283539], [1.270646860150478, 4.552258760161245, 0.36257723265892833, 0.0, 0.39390428570708846], [0.04706099482038807, 0.5989814158106901, 0.37427327242211955, 0.0, 0.0], [2.729537699582508, 2.7553145127291745, 2.6666970660076017, 0.0, 0.39390428570708846], [0.04706099482038807, 0.29949070790534504, 0.2924009940797809, 0.0, 1.5756171428283539], [0.04706099482038807, 0.5390832742296211, 0.37427327242211955, 0.0, 0.7878085714141769], [0.04706099482038807, 0.41928699106748313, 0.30409703384297215, 0.0, 0.7878085714141769], [0.04706099482038807, 0.41928699106748313, 0.30409703384297215, 0.0, 0.7878085714141769], [0.04706099482038807, 0.5390832742296211, 0.035088119289573706, 0.0, 0.0], [0.04706099482038807, 0.5989814158106901, 0.36257723265892833, 0.0, 0.0], [0.04706099482038807, 0.41928699106748313, 0.2924009940797809, 0.0, 0.7878085714141769], [0.21177447669174632, 0.41928699106748313, 0.023392079526382472, 0.0, 0.0], [0.04706099482038807, 0.41928699106748313, 0.3157930736061634, 0.0, 0.7878085714141769], [0.04706099482038807, 0.5989814158106901, 0.36257723265892833, 0.0, 0.0], [0.04706099482038807, 0.29949070790534504, 0.1286564373951036, 0.0, 2.363425714242531], [0.04706099482038807, 0.5390832742296211, 0.3157930736061634, 0.0, 0.0], [0.04706099482038807, 0.5390832742296211, 0.035088119289573706, 0.0, 0.0], [0.04706099482038807, 0.41928699106748313, 0.2924009940797809, 0.0, 0.7878085714141769], [0.04706099482038807, 0.4791851326485521, 0.3157930736061634, 0.0, 0.39390428570708846], [0.04706099482038807, 0.5390832742296211, 0.3157930736061634, 0.0, 0.0], [0.04706099482038807, 0.7187776989728282, 0.4093613917116933, 0.0, 0.0], [0.04706099482038807, 0.5390832742296211, 0.3157930736061634, 0.0, 0.7878085714141769], [1.5059518342524183, 6.588795573917592, 0.3274891133693546, 0.0, 0.39390428570708846], [0.14118298446116423, 0.4791851326485521, 0.3157930736061634, 0.0, 0.39390428570708846], [1.5765433264830004, 3.953277344350555, 0.28070495431658965, 0.0, 1.5756171428283539], [0.07059149223058211, 0.4791851326485521, 0.3157930736061634, 0.0, 0.39390428570708846], [0.04706099482038807, 0.29949070790534504, 0.2924009940797809, 0.0, 1.5756171428283539], [0.04706099482038807, 0.4791851326485521, 0.3157930736061634, 0.0, 0.39390428570708846], [0.04706099482038807, 0.6588795573917592, 0.035088119289573706, 0.0, 0.0], [0.04706099482038807, 0.4791851326485521, 0.3157930736061634, 0.0, 0.39390428570708846], [0.04706099482038807, 0.41928699106748313, 0.035088119289573706, 0.0, 0.0], [0.04706099482038807, 0.5989814158106901, 0.36257723265892833, 0.0, 0.0], [0.04706099482038807, 0.41928699106748313, 0.2924009940797809, 0.0, 0.7878085714141769], [0.04706099482038807, 0.4791851326485521, 0.3157930736061634, 0.0, 0.39390428570708846], [0.04706099482038807, 0.5989814158106901, 0.36257723265892833, 0.0, 0.0], [0.04706099482038807, 0.29949070790534504, 0.2924009940797809, 0.0, 1.5756171428283539], [0.04706099482038807, 0.5390832742296211, 0.2924009940797809, 0.0, 0.0], [0.04706099482038807, 0.4791851326485521, 0.3157930736061634, 0.0, 0.39390428570708846], [0.04706099482038807, 0.29949070790534504, 0.2924009940797809, 0.0, 1.5756171428283539], [0.04706099482038807, 0.29949070790534504, 0.1286564373951036, 0.0, 2.363425714242531], [0.04706099482038807, 0.4791851326485521, 0.3157930736061634, 0.0, 0.39390428570708846]]\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "0V_DFewg4cCn" + }, + "source": [ + "This cell is determining the number of keywords in each log and plotting them.\n", + "TODO: look at logs and find more keywords, instead of failures and successes make each word an entry in a matrix and use SVD to plot similarities" + ] + }, + { + "cell_type": "code", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 458 + }, + "id": "Did5do5Ga_TQ", + "outputId": "3c5cafb4-2d0e-41e7-8157-3d06f19c9cc0" + }, + "source": [ + "# ******* NINGXIAO *******\n", + "# find events in log, display frequecy of each event in a bar chart\n", + "import spacy\n", + "s = \"\"\n", + "for log in logs:\n", + " temp = \"\"\n", + " temp = temp.join(log)\n", + " s += temp\n", + "# Error Message: Text of length 5496377 exceeds maximum of 1000000.\n", + "s = s[0:100000]\n", + "nlp = spacy.load(\"en_core_web_sm\")\n", + "doc = nlp(s)\n", + "dictionary = {};\n", + "for token in doc:\n", + " if token.pos_ == 'VERB':\n", + " if token.text not in dictionary:\n", + " dictionary[token.text] = 1\n", + " else:\n", + " dictionary[token.text] += 1\n", + " #print(token.text, toekn.pos_)\n", + "\n", + "#print(dictionary)\n", + "\n", + "keys = list(dictionary.keys())\n", + "values = list(dictionary.values())\n", + "\n", + "fig, ax = plt.subplots(figsize=(9.2, 7)) \n", + "ax.barh(keys,values)\n", + "plt.title('Verbs in logs')\n", + "plt.ylabel('Verbs')\n", + "plt.xlabel('Frequency')\n", + "\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "R1oosA55NoQZ" + }, + "source": [ + "The image above shows the verbs and their frequency appear in the tokenized log text. It indicates what event and how often it happens in the log." + ] + } + ] +} \ No newline at end of file diff --git a/RedHatNLP/Deliverable4.ipynb b/RedHatNLP/Deliverable4.ipynb new file mode 100644 index 00000000..1b49f0a9 --- /dev/null +++ b/RedHatNLP/Deliverable4.ipynb @@ -0,0 +1,1389 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ocp-ci-analysis/RedHatNLP.ipynb at master · parkerwstone/ocp-ci-analysis + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+ + + +
+ + + + + + + + + +
+
+
+ + + + + + + + + + +
+ +
+ +
+

+ + + / + + ocp-ci-analysis + + +

+ + + forked from aicoe-aiops/ocp-ci-analysis + + +
+ +
    + +
  • + +
    + + + + + + + + Watch + + + + + +
    +
    +

    Notifications

    + +
    + +
    +
    + + + + + + + + +
    + +
    +
    +
    + + +
    +
    + +
    + + + +
  • + +
  • +
    +
    + + +
    +
    + + +
    + +
  • + +
  • +
    +
    + +
  • +
+ +
+ + + + +
+ + +
+
+ + + + +
+ + + + Permalink + + + +
+ +
+
+ + + master + + + +
+
+
+ Switch branches/tags + +
+ + + +
+ +
+ +
+ + +
+ +
+ + + + + + + + + + + +
+ + +
+
+
+
+ +
+ +
+ + + + Go to file + + +
+ + +
+
+
+ + + +
+ +
+
+
 
+
+ +
+
 
+ Cannot retrieve contributors at this time +
+
+ + + + + + + + + + + + +
+ + +
+
+ + + 3.43 MB +
+ +
+ +
+ Download +
+ +
+ + + + +
+ +
+
+
+ + + +
+ +
+
+ + + + +
Sorry, something went wrong. Reload?
+
Sorry, we cannot display this file.
+
Sorry, this file is invalid so it cannot be displayed.
+ +
+
+ +
+ + +
+ + + +
+ + +
+ + +
+
+ + +
+ + + +
+
+ +
+
+ +
+ + + + + + + + + + + + + + + + + + + diff --git a/RedHatNLP/Final_Analysis.ipynb b/RedHatNLP/Final_Analysis.ipynb new file mode 100644 index 00000000..17f348f5 --- /dev/null +++ b/RedHatNLP/Final_Analysis.ipynb @@ -0,0 +1,1348 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "name": "Final_Analysis", + "provenance": [], + "collapsed_sections": [] + }, + "kernelspec": { + "display_name": "Python 3", + "name": "python3" + } + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "P-SchSDwNCgQ" + }, + "source": [ + "

Red Hat NLP Spark Project

\n", + "\n", + "This notebook uses Red Hat's OpenShift data logs and processes them using Drain3. \n", + "\n", + "The first thing this notebook does is webscrape the OpenShift logs and installs dependencies. After, the logs are then cleaned by removing leading tags, dates, timestamps and other unique identifiers. This is done manually because Drain3 does not do this consistently for all logs. Finally the parsed logs are then fed into Drain3 and then put into a dictionary sorted by cluster ID.\n", + "\n", + "The final step that needs to be done is to sift out the pass and fail logs based on their cluster ID and visualize our data." + ] + }, + { + "cell_type": "code", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "z5cWx89XM9t6", + "outputId": "0e6ad8e0-73a2-4d65-dd8d-26c2b6912713" + }, + "source": [ + "!pip3 install drain3\n", + "!pip3 install kafka-python\n", + "!pip3 install redis\n", + "!pip install -q tf-models-official" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Collecting drain3\n", + " Downloading https://files.pythonhosted.org/packages/7e/1f/09c4ee7d648b66dda7dc8426e9cf9faeee71e544a2e7700d3d959e5cca59/drain3-0.9.5.tar.gz\n", + "Collecting jsonpickle==1.5.1\n", + " Downloading https://files.pythonhosted.org/packages/77/a7/c2f527ddce3155ae9e008385963c2325cbfd52969f8b38efa2723e2af4af/jsonpickle-1.5.1-py2.py3-none-any.whl\n", + "Requirement already satisfied: cachetools==4.2.1 in /usr/local/lib/python3.7/dist-packages (from drain3) (4.2.1)\n", + "Requirement already satisfied: importlib-metadata; python_version < \"3.8\" in /usr/local/lib/python3.7/dist-packages (from jsonpickle==1.5.1->drain3) (3.10.1)\n", + "Requirement already satisfied: zipp>=0.5 in /usr/local/lib/python3.7/dist-packages (from importlib-metadata; python_version < \"3.8\"->jsonpickle==1.5.1->drain3) (3.4.1)\n", + "Requirement already satisfied: typing-extensions>=3.6.4; python_version < \"3.8\" in /usr/local/lib/python3.7/dist-packages (from importlib-metadata; python_version < \"3.8\"->jsonpickle==1.5.1->drain3) (3.7.4.3)\n", + "Building wheels for collected packages: drain3\n", + " Building wheel for drain3 (setup.py) ... \u001b[?25l\u001b[?25hdone\n", + " Created wheel for drain3: filename=drain3-0.9.5-cp37-none-any.whl size=18179 sha256=df021c63200c550dc0982b1034ed467c35c5686e7d82a2590d27a205bb6ec15f\n", + " Stored in directory: /root/.cache/pip/wheels/11/a1/08/125223534f199f0db7a435b437015f83abba341ef0f4f6c64f\n", + "Successfully built drain3\n", + "Installing collected packages: jsonpickle, drain3\n", + "Successfully installed drain3-0.9.5 jsonpickle-1.5.1\n", + "Collecting kafka-python\n", + "\u001b[?25l Downloading https://files.pythonhosted.org/packages/75/68/dcb0db055309f680ab2931a3eeb22d865604b638acf8c914bedf4c1a0c8c/kafka_python-2.0.2-py2.py3-none-any.whl (246kB)\n", + "\u001b[K |████████████████████████████████| 256kB 5.8MB/s \n", + "\u001b[?25hInstalling collected packages: kafka-python\n", + "Successfully installed kafka-python-2.0.2\n", + "Collecting redis\n", + "\u001b[?25l Downloading https://files.pythonhosted.org/packages/a7/7c/24fb0511df653cf1a5d938d8f5d19802a88cef255706fdda242ff97e91b7/redis-3.5.3-py2.py3-none-any.whl (72kB)\n", + "\u001b[K |████████████████████████████████| 81kB 3.2MB/s \n", + "\u001b[?25hInstalling collected packages: redis\n", + "Successfully installed redis-3.5.3\n", + "\u001b[K |████████████████████████████████| 1.1MB 5.7MB/s \n", + "\u001b[K |████████████████████████████████| 174kB 13.4MB/s \n", + "\u001b[K |████████████████████████████████| 1.2MB 18.3MB/s \n", + "\u001b[K |████████████████████████████████| 51kB 5.1MB/s \n", + "\u001b[K |████████████████████████████████| 358kB 28.6MB/s \n", + "\u001b[K |████████████████████████████████| 706kB 28.8MB/s \n", + "\u001b[K |████████████████████████████████| 102kB 8.8MB/s \n", + "\u001b[K |████████████████████████████████| 645kB 39.7MB/s \n", + "\u001b[K |████████████████████████████████| 37.6MB 1.3MB/s \n", + "\u001b[?25h Building wheel for seqeval (setup.py) ... \u001b[?25l\u001b[?25hdone\n", + " Building wheel for py-cpuinfo (setup.py) ... \u001b[?25l\u001b[?25hdone\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Bq5k5nqiC02i" + }, + "source": [ + "from urllib.request import urlopen\n", + "from bs4 import BeautifulSoup\n", + "from google.colab import files\n", + "import pandas as pd\n", + "import io\n", + "import numpy as np\n", + "import dateutil\n", + "from dateutil import parser\n", + "import textblob\n", + "import requests\n", + "import matplotlib.pyplot as plt\n", + "import json\n", + "import pickle\n", + "import tensorflow as tf\n", + "from sklearn.ensemble import RandomForestClassifier\n", + "from sklearn.feature_extraction.text import TfidfVectorizer\n", + "from sklearn.model_selection import StratifiedShuffleSplit\n", + "\n", + "from sklearn.metrics import mean_squared_error\n", + "from sklearn.metrics import accuracy_score\n", + "from sklearn.metrics import precision_score\n", + "from sklearn.metrics import recall_score\n", + "from sklearn.metrics import f1_score\n", + "from sklearn.metrics import classification_report, confusion_matrix\n", + "from sklearn.model_selection import cross_val_score\n", + "from sklearn.metrics import mean_squared_error\n", + "\n", + "import drain3\n", + "from drain3 import TemplateMiner\n", + "import json\n", + "import logging\n", + "import sys\n", + "from drain3.kafka_persistence import KafkaPersistence\n", + "import re\n", + "\n", + "from sklearn.feature_extraction.text import TfidfVectorizer\n", + "from sklearn.model_selection import StratifiedShuffleSplit\n", + "\n", + "from sklearn.ensemble import RandomForestClassifier\n", + "from sklearn.metrics import mean_squared_error\n", + "from sklearn.model_selection import cross_val_score\n", + "from sklearn.metrics import classification_report, confusion_matrix\n", + "from sklearn.model_selection import cross_val_score\n", + "from sklearn.model_selection import RepeatedStratifiedKFold\n", + "import subprocess\n", + "import time\n", + "import spacy\n", + "\n", + "from xgboost import XGBClassifier\n", + "import os, os.path\n" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Iq11lna0RAee" + }, + "source": [ + "#

Dataset

\n", + "\n", + "Gather log files from OpenShift and save them to shared google drive, Red Hat & BU." + ] + }, + { + "cell_type": "code", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "st2dPqa-UuWF", + "outputId": "53eb705f-35a1-4a20-8f58-1ff0884534ac" + }, + "source": [ + "\n", + "#enable to read files from the google drive\n", + "from google.colab import drive\n", + "drive.mount('/content/drive')" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Mounted at /content/drive\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "3plLsNUbQdBo", + "outputId": "3182b287-4da0-4a2d-e2ca-32062109c696" + }, + "source": [ + "with open ('/content/drive/MyDrive/RedHat_BU/log/log_file_1.ob', 'rb') as fp:\n", + " logs1 = pickle.load(fp)\n", + "#print(logs[1])\n", + "\n", + "with open ('/content/drive/MyDrive/RedHat_BU/label/label_file_1.ob', 'rb') as fp:\n", + " labels1 = pickle.load(fp)\n", + "#print(labels)\n", + "\n", + "print(\"number of logs: \", len(logs1))\n", + "print(\"number of labels: \",len(labels1))" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "number of logs: 416\n", + "number of labels: 416\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "fj1i40jxS0MA", + "outputId": "a1c430d0-ea64-4b23-d857-58805df722b2" + }, + "source": [ + "#increase data size by twice (416+452=868)\n", + "with open ('/content/drive/MyDrive/RedHat_BU/log/log_file_2.ob', 'rb') as fp:\n", + " logs2 = pickle.load(fp)\n", + "#print(logs[1])\n", + "\n", + "with open ('/content/drive/MyDrive/RedHat_BU/label/label_file_2.ob', 'rb') as fp:\n", + " labels2 = pickle.load(fp)\n", + "#print(labels)\n", + "print(\"number of logs: \", len(logs2))\n", + "print(\"number of labels: \",len(labels2))" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "number of logs: 452\n", + "number of labels: 452\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "dhXs4CqLUs9n", + "outputId": "5228254b-00a2-44f0-bf2f-bddf283ad303" + }, + "source": [ + "#increase data size by 3 times (868+2958=3826)\n", + "with open ('/content/drive/MyDrive/RedHat_BU/log/log_file_3.ob', 'rb') as fp:\n", + " logs3 = pickle.load(fp)\n", + "#print(logs[1])\n", + "\n", + "with open ('/content/drive/MyDrive/RedHat_BU/label/label_file_3.ob', 'rb') as fp:\n", + " labels3 = pickle.load(fp)\n", + "#print(labels)\n", + "print(\"number of logs: \", len(logs3))\n", + "print(\"number of labels: \",len(labels3))" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "number of logs: 2958\n", + "number of labels: 2958\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "GvYhITN47N4P", + "outputId": "a289ff5c-34e5-41c5-802f-c43730f494f2" + }, + "source": [ + "#increase data size 3826+168=3994\n", + "with open ('/content/drive/MyDrive/RedHat_BU/log/log_file_4.ob', 'rb') as fp:\n", + " logs4 = pickle.load(fp)\n", + "#print(logs[1])\n", + "\n", + "with open ('/content/drive/MyDrive/RedHat_BU/label/label_file_4.ob', 'rb') as fp:\n", + " labels4 = pickle.load(fp)\n", + "#print(labels)\n", + "print(\"number of logs: \", len(logs4))\n", + "print(\"number of labels: \",len(labels4))" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "number of logs: 168\n", + "number of labels: 168\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "18ETd8BvS3Ne", + "outputId": "472993c0-04ae-4462-b694-6ed768a32547" + }, + "source": [ + "logs = logs1# + logs2 + logs3 + logs4 \n", + "labels = labels1# + labels2 + labels3 + labels4 \n", + "print(\"number of logs: \", len(logs))\n", + "print(\"number of labels: \",len(labels))" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "number of logs: 416\n", + "number of labels: 416\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "heDQxXYAQzcU" + }, + "source": [ + "#

Assigning Labels to Logs

" + ] + }, + { + "cell_type": "code", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "S056NuDx71Wt", + "outputId": "355a0485-8e06-49f3-c0fb-215b0e30d8fc" + }, + "source": [ + "# 1 := success, 0 := fail\n", + "y = []\n", + "count_0 = 0\n", + "count_1 = 0\n", + "for label in labels:\n", + " if label == 'SUCCESS':\n", + " y.append(1)\n", + " count_1 = count_1 + 1\n", + " else:\n", + " y.append(0)\n", + " count_0 = count_0 + 1\n", + "print(\"y = \", y)\n", + "print(\"number of success/1 = \", count_1)\n", + "print(\"number of fail/0 = \", count_0)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "y = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]\n", + "number of success/1 = 276\n", + "number of fail/0 = 140\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "pb5gAOrHQ67U" + }, + "source": [ + "

Splitting log lines for vectorization

" + ] + }, + { + "cell_type": "code", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "BuzkkC0dOamf", + "outputId": "ff7da8e0-bc17-425c-8691-0e7588906346" + }, + "source": [ + "vocab = {}\n", + "i = 0\n", + "for log in logs:\n", + " log = str(log).split(\",\")\n", + " for line in log:\n", + " line = line.replace(\"'\",\"\").replace(\" \",\"\").replace(\"\\\"\",\"\")\n", + " if line not in vocab:\n", + " vocab[line] = i\n", + " i+=1\n", + "print(len(vocab))" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "39584\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "d__aAxaiXGmG" + }, + "source": [ + "#print(list(vocab.items())[:100])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "aTYgLuEaRHiX" + }, + "source": [ + "#

Classifying logs without Drain3 and parsing

\n", + "\n", + "Here begins the process of vectorizing each log line and then classifying it as a pass or fail log accordingly. If this cell has an error, run the cell that removes newline characters and the leading b' tag from the logs." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "sUhrDxlNO7JS" + }, + "source": [ + "vectorizer = TfidfVectorizer(vocabulary = vocab)\n", + "\n", + "X = vectorizer.fit_transform(logs)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "ukvCx6NDUhU5", + "outputId": "ae14ab29-26f9-4463-bbc0-0aa3e04f047c" + }, + "source": [ + "X.shape" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(416, 39584)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 37 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "TPerlihUQUkT" + }, + "source": [ + "sss = StratifiedShuffleSplit(n_splits=1, test_size=0.2, train_size= 0.8, random_state=1)\n", + "sss.get_n_splits(X, y)\n", + "y = np.array(y)\n", + "for train_index, test_index in sss.split(X, y):\n", + " X_train, X_test = X[train_index], X[test_index]\n", + " y_train, y_test = y[train_index], y[test_index]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "JjhiyTqNr9Gs", + "outputId": "86dfda38-01f1-40de-9330-cdae8b583274" + }, + "source": [ + "#tfidf\n", + "X_train.shape" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(332, 39584)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 39 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "BJcVgQrOVeI-" + }, + "source": [ + "# Classifying logs without Drain3 with XGB\n", + "\n", + "\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "SMY0yIo1zt4d" + }, + "source": [ + "#training accuracy calculator\n", + "def accuracy_cal(prediction, Testy):\n", + " count = 0\n", + " for i in range(len(prediction)):\n", + " if prediction[i] == int(Testy[i]):\n", + " count+=1\n", + " accuracy = round(count / len(prediction) * 100, 4)\n", + " #print(accuracy, \"%\")\n", + " return accuracy\n", + "\n" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "WAm7oirNUc9P", + "outputId": "b30b7878-e930-47f8-dbf3-d1f849bcc3a0" + }, + "source": [ + "model_XGB = XGBClassifier(scale_pos_weight=99).fit(X_train, y_train)\n", + "y_test_predictions = model_XGB.predict(X_test)\n", + "accuracy = accuracy_cal(y_test_predictions, y_test)\n", + "\n", + "y_train_predictions = model_XGB.predict(X_train)\n", + "training_error = mean_squared_error(y_train,y_train_predictions)\n", + "\n", + "\n", + "print(\"=== Confusion Matrix ===\")\n", + "print(confusion_matrix(y_test, y_test_predictions))\n", + "\n", + "print(\"=== Classification Report ===\")\n", + "print(classification_report(y_test, y_test_predictions))\n", + "\n", + "print(\"Training error: \",round(training_error,4))\n", + "print(\"Training accuracy: \", accuracy,\"%\")\n", + "print(\"Precision score: {}\".format(precision_score(y_test, y_test_predictions)))\n", + "print(\"Recall score: {}\".format(recall_score(y_test, y_test_predictions)))\n", + "print(\"F1 Score: {}\".format(f1_score(y_test, y_test_predictions)))" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "=== Confusion Matrix ===\n", + "[[24 4]\n", + " [ 0 56]]\n", + "=== Classification Report ===\n", + " precision recall f1-score support\n", + "\n", + " 0 1.00 0.86 0.92 28\n", + " 1 0.93 1.00 0.97 56\n", + "\n", + " accuracy 0.95 84\n", + " macro avg 0.97 0.93 0.94 84\n", + "weighted avg 0.96 0.95 0.95 84\n", + "\n", + "Training error: 0.0422\n", + "Training accuracy: 95.2381 %\n", + "Precision score: 0.9333333333333333\n", + "Recall score: 1.0\n", + "F1 Score: 0.9655172413793104\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "BPdgFG7Da0Pw" + }, + "source": [ + "\n" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4UBShV3kRskG" + }, + "source": [ + "#

Parsing logs before processing into Drain3

\n", + "\n", + "Logs need to be parsed before processing into Drain3. This is necessary because Drain3 does not parse consistently for every log.\n", + "\n", + "Things to be parsed:\n", + "
    \n", + "
  • Dates
  • \n", + "
  • Timestamps
  • \n", + "
  • Newline characters
  • \n", + "
  • Version numbers
  • \n", + "
  • Namespace IDs
  • \n", + "
  • URLs
  • \n", + "
" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "pfWCburJvXQA" + }, + "source": [ + "original_log = logs[1]\n", + "#print(original_log)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "aRyol0yU4HP_" + }, + "source": [ + "# helper function detecting if a string is a date / timestamp\n", + "parsed_logs = []\n", + "def is_date(str):\n", + " try:\n", + " dateutil.parser.parse(str)\n", + " return True\n", + " except:\n", + " return False\n", + "for i in range(len(logs)):\n", + " # splitting each section as its own index (for parsing)\n", + " parsed_logs.append(str(logs[i]).split(' '))\n", + " for j in range(len(parsed_logs[i])):\n", + " if is_date(parsed_logs[i][j]) == True:\n", + " parsed_logs[i][j] = ''\n", + " parsed_logs[i] = list(filter(lambda x: x != '', parsed_logs[i]))\n", + " parsed_logs[i] = ' '.join(parsed_logs[i])" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "tSINSnQeDqZ9" + }, + "source": [ + "This code cell removes timestamps and dates in order to mitigate unique identifiers" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "L8a8Nyc76PQo" + }, + "source": [ + "for index in range(len(parsed_logs)):\n", + " # removing version number\n", + " if \"version\" in parsed_logs[index]:\n", + " tmp = parsed_logs[index].split(\"version\",1)\n", + " tmp_1 = tmp[0]\n", + " tmp_2 = tmp[1].split()\n", + " tmp_2 = tmp_2[1:]\n", + " tmp = ''.join(tmp_1) + ' '.join(tmp_2)\n", + " parsed_logs[index] = tmp\n", + "\n", + " # removing creating namespace ID\n", + " if \"Creating namespace\" in parsed_logs[index]:\n", + " tmp = parsed_logs[index].split(\"Creating namespace\", 1)\n", + " tmp_1 = tmp[0]\n", + " tmp_2 = tmp[1].split()\n", + " tmp_2 = tmp_2[1:]\n", + " tmp = ''.join(tmp_1) + ' '.join(tmp_2)\n", + " parsed_logs[index] = tmp\n", + "\n", + " # removing using namespace ID\n", + " if \"Using namespace\" in parsed_logs[index]:\n", + " tmp = parsed_logs[index].split(\"Using namespace\", 1)\n", + " tmp_1 = tmp[0]\n", + " tmp_2 = tmp[1].split()\n", + " tmp_2 = tmp_2[1:]\n", + " tmp = ''.join(tmp_1) + ' '.join(tmp_2)\n", + " parsed_logs[index] = tmp\n", + "\n", + " # removing Imported release stamp\n", + " if \"Imported release\" in parsed_logs[index]:\n", + " tmp = parsed_logs[index].split(\"Imported release\", 1)\n", + " tmp_1 = tmp[0]\n", + " tmp_2 = tmp[1].split()\n", + " tmp_2 = tmp_2[1:]\n", + " tmp = ''.join(tmp_1) + ' '.join(tmp_2)\n", + " parsed_logs[index] = tmp\n", + "\n", + " # removing Acquired lease stamp\n", + " if \"Acquired lease\" in parsed_logs[index]:\n", + " tmp = parsed_logs[index].split(\"Acquired lease\", 1)\n", + " tmp_1 = tmp[0]\n", + " tmp_2 = tmp[1].split()\n", + " tmp_2 = tmp_2[1:]\n", + " tmp = ''.join(tmp_1) + ' '.join(tmp_2)\n", + " parsed_logs[index] = tmp\n", + "\n", + " # removing \"images will be pullable from\" link\n", + " if \"images will be pullable from\" in parsed_logs[index]:\n", + " tmp = parsed_logs[index].split(\"images will be pullable from\", 1)\n", + " tmp_1 = tmp[0]\n", + " tmp_2 = tmp[1].split()\n", + " tmp_2 = tmp_2[1:]\n", + " tmp = ''.join(tmp_1) + ' '.join(tmp_2)\n", + " parsed_logs[index] = tmp" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "RDSHV7fZTOBT" + }, + "source": [ + "#

Drain3 Processing

\n", + "\n", + "The parsed logs are now being processed in Drain3. Drain3 will do additional parsing and also cluster the logs. Drain3 uses longest common subsequence as their algorithm for clustering, so logs with similar structure will be considered to be in the same clustering. There are two dictionaries that represent the size of each cluster and another that separates the logs by cluster ID. The goal of this is to determine which clusters are pass logs and which clusters are fail logs." + ] + }, + { + "cell_type": "code", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "WtFxnlMOmp3W", + "outputId": "f461ceaa-2a1f-49d4-ede5-e9ac55abe0de" + }, + "source": [ + "\n", + "template_miner = TemplateMiner(None)\n", + "i = 0\n", + "ints_from_drain = []\n", + "while True:\n", + " if i >= len(parsed_logs):\n", + " break\n", + " log_line = ' '.join(parsed_logs[i])\n", + " i += 1\n", + " if log_line == 'q':\n", + " break\n", + " result = template_miner.add_log_message(log_line)\n", + " result_json = json.dumps(result)\n", + " ints_from_drain.append(re.findall(r'\\d+', result_json))\n", + " # print(result_json)\n", + "\n", + "ints_from_drain = np.asarray(ints_from_drain)\n", + "\n", + "cluster_size = {}\n", + "cluster_id = {}\n", + "for cluster in template_miner.drain.clusters:\n", + " if cluster.cluster_id not in cluster_size:\n", + " cluster_size[cluster.cluster_id] = cluster.size\n", + " cluster_id[cluster.cluster_id] = []\n", + "\n", + "\n", + "for i in range(len(ints_from_drain)):\n", + " cluster_id[int(ints_from_drain[i][0])].append(parsed_logs[i])\n", + "\n", + "print(cluster_size)\n" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "WARNING:drain3.template_miner_config:config file not found: drain3.ini\n" + ], + "name": "stderr" + }, + { + "output_type": "stream", + "text": [ + "{1: 1, 2: 1, 3: 1, 4: 1, 5: 1, 6: 1, 7: 1, 8: 1, 9: 1, 10: 1, 11: 2, 12: 1, 13: 1, 14: 1, 15: 1, 16: 1, 17: 1, 18: 1, 19: 1, 20: 1, 21: 1, 22: 1, 23: 1, 24: 1, 25: 1, 26: 1, 27: 1, 28: 1, 29: 1, 30: 1, 31: 1, 32: 1, 33: 1, 34: 1, 35: 1, 36: 1, 37: 1, 38: 1, 39: 1, 40: 1, 41: 1, 42: 1, 43: 1, 44: 1, 45: 1, 46: 1, 47: 1, 48: 1, 49: 1, 50: 1, 51: 1, 52: 1, 53: 1, 54: 1, 55: 1, 56: 1, 57: 1, 58: 1, 59: 1, 60: 1, 61: 1, 62: 1, 63: 1, 64: 1, 65: 1, 66: 1, 67: 1, 68: 1, 69: 1, 70: 1, 71: 1, 72: 1, 73: 1, 74: 1, 75: 1, 76: 1, 77: 1, 78: 1, 79: 1, 80: 1, 81: 1, 82: 1, 83: 1, 84: 1, 85: 1, 86: 1, 87: 1, 88: 1, 89: 1, 90: 10, 91: 2, 92: 16, 93: 10, 94: 2, 95: 10, 96: 2, 97: 4, 98: 2, 99: 2, 100: 12, 101: 2, 102: 2, 103: 2, 104: 6, 105: 2, 106: 2, 107: 2, 108: 2, 109: 34, 110: 2, 111: 2, 112: 2, 113: 2, 114: 6, 115: 2, 116: 2, 117: 2, 118: 20, 119: 2, 120: 2, 121: 2, 122: 2, 123: 2, 124: 6, 125: 2, 126: 6, 127: 4, 128: 74, 129: 8, 130: 2, 131: 2, 132: 2, 133: 2, 134: 6, 135: 4, 136: 2, 137: 2, 138: 2, 139: 2, 140: 2, 141: 2, 142: 2, 143: 4, 144: 2, 145: 2, 146: 2, 147: 4, 148: 2, 149: 2}\n" + ], + "name": "stdout" + }, + { + "output_type": "stream", + "text": [ + "/usr/local/lib/python3.7/dist-packages/numpy/core/_asarray.py:83: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray\n", + " return array(a, dtype, copy=False, order=order)\n" + ], + "name": "stderr" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "UlznByNoD3w1" + }, + "source": [ + "#

Parsing Results Print out

\n", + "\n", + "Here is a snippet example of what the parsing process does to each log. As you can see the leading byte tag, dates, and unique URLs will be parsed out from both manual parsing and Drain3." + ] + }, + { + "cell_type": "code", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "6rqae9VQDaoS", + "outputId": "053fe8d2-9148-491d-99a8-4f21ab5ac999" + }, + "source": [ + "print(original_log.split(',')[:3])\n", + "print(parsed_logs[1].split(',')[:3])" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "['b\\'2020/10/28 22:31:45 ci-operator version v20201028-4f6c4ca\"', \" '2020/10/28 22:31:45 No source defined'\", \" '2020/10/28 22:31:45 Resolved release latest to registry.svc.ci.openshift.org/ocp/release:4.5-ci'\"]\n", + "[\"b'2020/10/28 ci-operator No source defined'\", \" Resolved release latest to registry.svc.ci.openshift.org/ocp/release:4.5-ci'\", ' Running [release-inputs]']\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "aMuEAdZvVZUX" + }, + "source": [ + "#

Log cluster example

\n", + "\n", + "Here is a printout of logs that fall under a cluster with the ID of 94. This cluster contains the most amount of data logs. Based on the clustering algorithm it is evident that Drain3 uses longest common sequence because all of these logs in this cluster contain the exact same structure with very small differences, especially after being parsed." + ] + }, + { + "cell_type": "code", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "Rx-UE8x2VXRg", + "outputId": "d9be061b-1a75-49c6-8f45-6168cd442339" + }, + "source": [ + "i = 1\n", + "for log in cluster_id[95]:\n", + " print(\"log\", i, \":\", log[:200], \"...\")\n", + " print()\n", + " i += 1" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "log 1 : b'2020/11/10 ci-operator No source defined', Resolved release latest to registry.svc.ci.openshift.org/ocp/release:4.1', warning: overriding parameter \"LEASED_RESOURCE\"', Running [release-inputs], e2e- ...\n", + "\n", + "log 2 : b'2020/11/11 ci-operator No source defined', Resolved release latest to registry.svc.ci.openshift.org/ocp/release:4.1', warning: overriding parameter \"LEASED_RESOURCE\"', Running [release-inputs], e2e- ...\n", + "\n", + "log 3 : b'2020/11/12 ci-operator No source defined', Resolved release latest to registry.svc.ci.openshift.org/ocp/release:4.1', warning: overriding parameter \"LEASED_RESOURCE\"', Running [release-inputs], e2e- ...\n", + "\n", + "log 4 : b'2020/11/13 ci-operator No source defined', Resolved release latest to registry.svc.ci.openshift.org/ocp/release:4.1', warning: overriding parameter \"LEASED_RESOURCE\"', Running [release-inputs], e2e- ...\n", + "\n", + "log 5 : b'2020/11/15 ci-operator No source defined', Resolved release latest to registry.svc.ci.openshift.org/ocp/release:4.1', warning: overriding parameter \"LEASED_RESOURCE\"', Running [release-inputs], e2e- ...\n", + "\n", + "log 6 : b'2020/11/10 ci-operator No source defined', Resolved release latest to registry.svc.ci.openshift.org/ocp/release:4.1', warning: overriding parameter \"LEASED_RESOURCE\"', Running [release-inputs], e2e- ...\n", + "\n", + "log 7 : b'2020/11/11 ci-operator No source defined', Resolved release latest to registry.svc.ci.openshift.org/ocp/release:4.1', warning: overriding parameter \"LEASED_RESOURCE\"', Running [release-inputs], e2e- ...\n", + "\n", + "log 8 : b'2020/11/12 ci-operator No source defined', Resolved release latest to registry.svc.ci.openshift.org/ocp/release:4.1', warning: overriding parameter \"LEASED_RESOURCE\"', Running [release-inputs], e2e- ...\n", + "\n", + "log 9 : b'2020/11/13 ci-operator No source defined', Resolved release latest to registry.svc.ci.openshift.org/ocp/release:4.1', warning: overriding parameter \"LEASED_RESOURCE\"', Running [release-inputs], e2e- ...\n", + "\n", + "log 10 : b'2020/11/15 ci-operator No source defined', Resolved release latest to registry.svc.ci.openshift.org/ocp/release:4.1', warning: overriding parameter \"LEASED_RESOURCE\"', Running [release-inputs], e2e- ...\n", + "\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "yMgfiryITDZ5" + }, + "source": [ + "#

Classifying logs with Drain3 and parsing

" + ] + }, + { + "cell_type": "code", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "Zm8de6q1RvAx", + "outputId": "266cdb52-5b5e-4caf-eb2e-1ab729a05db7" + }, + "source": [ + "vocab = {}\n", + "i = 0\n", + "hhh = []\n", + "for log in parsed_logs:\n", + " log = str(log).split(\",\")\n", + " for line in log:\n", + " line = line.replace(\"'\",\"\").replace(\" \",\"\").replace(\"\\\"\",\"\")\n", + " if line not in vocab:\n", + " vocab[line] = i\n", + " i+=1\n", + "print(len(vocab))\n", + "# print(hhh)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "27820\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "feNguNBnV7c_" + }, + "source": [ + "

Vectorizing log lines

" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "M-7kd8rRR4qL" + }, + "source": [ + "vectorizer = TfidfVectorizer(vocabulary = vocab)\n", + "X2 = vectorizer.fit_transform(parsed_logs)\n" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "LEYrmPmGWeK3", + "outputId": "d778b6ce-f857-4cc4-ceaa-18ffc8ff7e34" + }, + "source": [ + "print(X2.shape)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "(416, 27820)\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "gfJt0J1bR9ir" + }, + "source": [ + "sss = StratifiedShuffleSplit(n_splits=1, test_size=0.2, train_size= 0.8, random_state=1)\n", + "sss.get_n_splits(X2, y)\n", + "y = np.array(y)\n", + "for train_index, test_index in sss.split(X2, y):\n", + " X_train2, X_test2 = X2[train_index], X2[test_index]\n", + " y_train, y_test = y[train_index], y[test_index]" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "fdOevl5l1Hxt", + "outputId": "6740e176-0687-4842-c4e7-8c2b77e07ac6" + }, + "source": [ + "#tfidf\n", + "X_train2.shape" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(332, 27820)" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 52 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6tvepY3kYhXJ" + }, + "source": [ + "# Classifying logs with Drain3 with XGB" + ] + }, + { + "cell_type": "code", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "avuHz_QVYl3_", + "outputId": "aa333d26-4768-4d83-a547-2fa632c22902" + }, + "source": [ + "model_XGB_D = XGBClassifier(scale_pos_weight=99).fit(X_train2, y_train)\n", + "y_test_predictions = model_XGB_D.predict(X_test2)\n", + "accuracy = accuracy_cal(y_test_predictions, y_test)\n", + "\n", + "y_train_predictions = model_XGB_D.predict(X_train2)\n", + "training_error = mean_squared_error(y_train,y_train_predictions)\n", + "\n", + "\n", + "print(\"=== Confusion Matrix ===\")\n", + "print(confusion_matrix(y_test, y_test_predictions))\n", + "\n", + "print(\"=== Classification Report ===\")\n", + "print(classification_report(y_test, y_test_predictions))\n", + "\n", + "\n", + "print(\"Training error: \",round(training_error,4))\n", + "print(\"Training accuracy: \", accuracy,\"%\")\n", + "print(\"Precision score: {}\".format(precision_score(y_test, y_test_predictions)))\n", + "print(\"Recall score: {}\".format(recall_score(y_test, y_test_predictions)))\n", + "print(\"F1 Score: {}\".format(f1_score(y_test, y_test_predictions)))" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "=== Confusion Matrix ===\n", + "[[21 7]\n", + " [ 0 56]]\n", + "=== Classification Report ===\n", + " precision recall f1-score support\n", + "\n", + " 0 1.00 0.75 0.86 28\n", + " 1 0.89 1.00 0.94 56\n", + "\n", + " accuracy 0.92 84\n", + " macro avg 0.94 0.88 0.90 84\n", + "weighted avg 0.93 0.92 0.91 84\n", + "\n", + "Training error: 0.0753\n", + "Training accuracy: 91.6667 %\n", + "Precision score: 0.8888888888888888\n", + "Recall score: 1.0\n", + "F1 Score: 0.9411764705882353\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "sTiDDkU5Oqy8" + }, + "source": [ + "#Visualizations\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "IuBApuTZEjjW" + }, + "source": [ + "k = [100,200,300,400,416]\n", + "#k = [200,400,600,800,868]\n", + "#k = [700,1400,2100,2800,3500,3826]\n", + "#k = [500,1000,1500,2000,2500,3000,3500,3994]\n", + "sdp=[]\n", + "snp=[]\n", + "sdf1=[]\n", + "snf1=[]\n", + "acc_n = []\n", + "acc_d = []\n", + "X[0:k[0]].shape\n", + "for i in range(len(k)):\n", + " DrainX = X[0:k[i]]\n", + " NoDrainX = X2[0:k[i]]\n", + " lb = y[0:k[i]]\n", + " sss = StratifiedShuffleSplit(n_splits=1, test_size=0.2, train_size= 0.8, random_state=1)\n", + " sss.get_n_splits(DrainX, lb)\n", + " lb = np.array(lb)\n", + " for train_index, test_index in sss.split(DrainX, lb):\n", + " Xd_train, Xd_test = DrainX[train_index], DrainX[test_index] \n", + " Xn_train, Xn_test = NoDrainX[train_index], NoDrainX[test_index] \n", + " y_train, y_test = lb[train_index], lb[test_index]\n", + "\n", + " model_XGB_D = XGBClassifier(scale_pos_weight=99).fit(Xd_train, y_train) \n", + " yd_test_predictions = model_XGB_D.predict(Xd_test)\n", + " sd_pre = precision_score(y_test, yd_test_predictions)\n", + " sdp.append(sd_pre)\n", + " sd_f1 = f1_score(y_test, yd_test_predictions)\n", + " sdf1.append(sd_f1)\n", + " acc_d.append(accuracy_cal(yd_test_predictions, y_test))\n", + "\n", + " model_XGB = XGBClassifier(scale_pos_weight=99).fit(Xn_train, y_train) \n", + " yn_test_predictions = model_XGB.predict(Xn_test)\n", + " sn_pre = precision_score(y_test, yn_test_predictions)\n", + " snp.append(sn_pre)\n", + " sn_f1 = f1_score(y_test, yn_test_predictions)\n", + " snf1.append(sn_f1)\n", + " acc_n.append(accuracy_cal(yn_test_predictions, y_test))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 513 + }, + "id": "r7TIRdELWein", + "outputId": "27e4b6e4-c7ad-4edf-c793-a7294b2bc6e9" + }, + "source": [ + "fig = plt.figure(figsize=(6,8))\n", + "\n", + "fig.subplots_adjust(hspace=1.4, wspace=1.4)\n", + "ax = fig.add_subplot(3, 1, 1)\n", + "ax.plot(k, acc_d, label = \"XGB_Drain\")\n", + "ax.plot(k, acc_n, label = \"XGB\")\n", + "plt.xlabel(\"number of data\")\n", + "plt.ylabel(\"accuracy\")\n", + "plt.title('Accuracy of classification for log data with and without processing')\n", + "plt.legend()\n", + "\n", + "ax = fig.add_subplot(3, 1, 2)\n", + "ax.plot(k, sdp, label = \"XGB\")\n", + "ax.plot(k, snp, label = \"XGB_Drain\")\n", + "plt.xlabel(\"number of data\")\n", + "plt.ylabel(\"precision score\")\n", + "plt.title('Precision score of classification for log data with and without processing')\n", + "plt.legend()\n", + "\n", + "ax = fig.add_subplot(3, 1, 3)\n", + "ax.plot(k, sdf1, label = \"XGB_Drain\")\n", + "ax.plot(k, snf1, label = \"XGB\")\n", + "plt.xlabel(\"number of data\")\n", + "plt.ylabel(\"F1 score\")\n", + "plt.title('F1 score of classification for log data with and without processing')\n", + "plt.legend()\n", + "plt.show()" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Hth_ioBpm7_7" + }, + "source": [ + "#

Cross validation

\n", + "the code below it to verify if there is overfit in our model when the dataset size changes\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "iZbqDPOQjdTK" + }, + "source": [ + "k = [100,200,300,400,416]\n", + "#k = [200,400,600,800,868]\n", + "#k = [700,1400,2100,2800,3500,3826]\n", + "#k = [500,1000,1500,2000,2500,3000,3500,3994]\n", + "scores_d = [] #Drain\n", + "scores_s = [] #No Drain\n", + "for i in range(len(k)):\n", + " DrainX = X[0:k[i]]\n", + " NoDrainX = X2[0:k[i]]\n", + " lb = y[0:k[i]]\n", + " cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1)\n", + " # evaluate model\n", + " scores_d.append(np.mean(cross_val_score(model_XGB_D, DrainX, lb, scoring='roc_auc', cv=cv, n_jobs=-1)))\n", + " \n", + " cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1)\n", + " # evaluate model\n", + " scores_s.append(np.mean(cross_val_score(model_XGB, NoDrainX, lb, scoring='roc_auc', cv=cv, n_jobs=-1)))\n" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "faXyTLBlj8wE", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 313 + }, + "outputId": "9840fb21-eae1-4bc6-defc-b9feb70d85d9" + }, + "source": [ + "#fig = plt.figure(figsize=(6,8))\n", + "\n", + "\n", + "plt.plot(k, scores_d, label = \"XGB\")\n", + "plt.plot(k, scores_s, label = \"XGB_Drain\")\n", + "plt.xlabel(\"number of data\")\n", + "plt.ylabel(\"roc_auc\")\n", + "plt.title('Compute Area Under the Receiver Operating Characteristic Curve (ROC AUC) from prediction scores')\n", + "plt.legend()\n" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 59 + }, + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "tags": [], + "needs_background": "light" + } + } + ] + } + ] +} \ No newline at end of file diff --git a/RedHatNLP/Final_WebScraping.ipynb b/RedHatNLP/Final_WebScraping.ipynb new file mode 100644 index 00000000..4808c0d7 --- /dev/null +++ b/RedHatNLP/Final_WebScraping.ipynb @@ -0,0 +1,506 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "name": "Final_WebScraping", + "provenance": [], + "collapsed_sections": [] + }, + "kernelspec": { + "display_name": "Python 3", + "name": "python3" + } + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "P-SchSDwNCgQ" + }, + "source": [ + "

Web Scraping for NLP Project

\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Bq5k5nqiC02i" + }, + "source": [ + "from urllib.request import urlopen\n", + "from bs4 import BeautifulSoup\n", + "from google.colab import files\n", + "import pandas as pd\n", + "import io\n", + "import numpy as np\n", + "import dateutil\n", + "from dateutil import parser\n", + "import textblob\n", + "import requests\n", + "import matplotlib.pyplot as plt\n", + "import json\n", + "\n", + "from sklearn.ensemble import RandomForestClassifier\n", + "from sklearn.feature_extraction.text import TfidfVectorizer\n", + "from sklearn.model_selection import StratifiedShuffleSplit\n", + "\n", + "from sklearn.metrics import mean_squared_error\n", + "from sklearn.metrics import accuracy_score\n", + "from sklearn.metrics import precision_score\n", + "from sklearn.metrics import recall_score\n", + "from sklearn.metrics import f1_score\n", + "from sklearn.metrics import classification_report, confusion_matrix\n", + "\n", + "\n", + "\n", + "import json\n", + "import logging\n", + "import sys\n", + "import re\n", + "\n", + "from sklearn.feature_extraction.text import TfidfVectorizer\n", + "from sklearn.model_selection import StratifiedShuffleSplit\n", + "\n", + "from sklearn.ensemble import RandomForestClassifier\n", + "from sklearn.metrics import mean_squared_error\n", + "from sklearn.model_selection import cross_val_score\n", + "from sklearn.metrics import classification_report, confusion_matrix\n", + "import subprocess\n", + "import time\n", + "import spacy\n", + "import pickle\n", + "from xgboost import XGBClassifier" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "kE517G6j_3Su", + "colab": { + "base_uri": "https://localhost:8080/" + }, + "outputId": "78e7e923-3795-40ab-96da-860ce5f830c0" + }, + "source": [ + "from google.colab import drive\n", + "drive.mount('/content/drive')" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Mounted at /content/drive\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Iq11lna0RAee" + }, + "source": [ + "#

Web scraping

\n", + "\n", + "Gathers OpenShift using BeautifulSoup and then returns an array containing all of the logs." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "XHDHu0nR9RFe" + }, + "source": [ + "#log_file_1\n", + "base1 =\"https://gcsweb-ci.apps.ci.l2s4.p1.openshiftapps.com/gcs/origin-ci-test/logs/canary-release-openshift-origin-installer-e2e-aws-4.5-cnv/\"\n", + "base2 =\"https://gcsweb-ci.apps.ci.l2s4.p1.openshiftapps.com/gcs/origin-ci-test/logs/release-openshift-ocp-installer-e2e-aws-serial-4.1/\"\n", + "base3 =\"https://gcsweb-ci.apps.ci.l2s4.p1.openshiftapps.com/gcs/origin-ci-test/logs/release-openshift-ocp-installer-e2e-aws-serial-4.3/\"\n", + "\n", + "#log_file_2\n", + "base4 =\"https://gcsweb-ci.apps.ci.l2s4.p1.openshiftapps.com/gcs/origin-ci-test/logs/branch-ci-open-cluster-management-governance-policy-propagator-main-images/\"\n", + "base5 =\"https://gcsweb-ci.apps.ci.l2s4.p1.openshiftapps.com/gcs/origin-ci-test/logs/branch-ci-open-cluster-management-console-release-2.3-images/\"\n", + "base6 =\"https://gcsweb-ci.apps.ci.l2s4.p1.openshiftapps.com/gcs/origin-ci-test/logs/branch-ci-kubevirt-hyperconverged-cluster-operator-release-4.9-images/\"\n", + "base7=\"https://gcsweb-ci.apps.ci.l2s4.p1.openshiftapps.com/gcs/origin-ci-test/logs/branch-ci-openshift-tektoncd-triggers-release-next-4.5-images/\"\n", + "base8=\"https://gcsweb-ci.apps.ci.l2s4.p1.openshiftapps.com/gcs/origin-ci-test/logs/branch-ci-openshift-local-storage-operator-master-images/\"\n", + "base9=\"https://gcsweb-ci.apps.ci.l2s4.p1.openshiftapps.com/gcs/origin-ci-test/logs/periodic-ci-openshift-release-master-ci-4.5-e2e-aws-upgrade-rollback/\"\n", + "\n", + "#log_file_3\n", + "base10 =\"https://gcsweb-ci.apps.ci.l2s4.p1.openshiftapps.com/gcs/origin-ci-test/logs/branch-ci-codeready-toolchain-host-operator-master-test/\"\n", + "base11 =\"https://gcsweb-ci.apps.ci.l2s4.p1.openshiftapps.com/gcs/origin-ci-test/logs/branch-ci-integr8ly-integreatly-operator-3scale-next-0.7.0-images/\"\n", + "base12 =\"https://gcsweb-ci.apps.ci.l2s4.p1.openshiftapps.com/gcs/origin-ci-test/logs/branch-ci-open-cluster-management-multicloud-operators-foundation-master-fast-forward/\"\n", + "\n", + "#log_file_4\n", + "base13 =\"https://gcsweb-ci.apps.ci.l2s4.p1.openshiftapps.com/gcs/origin-ci-test/logs/periodic-ci-red-hat-data-services-opendatahub-operator-master-modh-operator-e2e-nightly/\"\n", + "base14 =\"https://gcsweb-ci.apps.ci.l2s4.p1.openshiftapps.com/gcs/origin-ci-test/logs/release-openshift-origin-installer-e2e-aws-sdn-multitenant-4.6/\"\n", + "\n", + "#log_file_5\n", + "base15 =\"https://gcsweb-ci.apps.ci.l2s4.p1.openshiftapps.com/gcs/origin-ci-test/logs/periodic-ci-openshift-release-master-ocp-4.5-ci-e2e-44-stable-to-45-ci/\"\n", + "base16 =\"https://gcsweb-ci.apps.ci.l2s4.p1.openshiftapps.com/gcs/origin-ci-test/logs/periodic-ci-openshift-release-master-ocp-4.7-e2e-metal-assisted-onprem/\"\n", + "base17 = \"https://gcsweb-ci.apps.ci.l2s4.p1.openshiftapps.com/gcs/origin-ci-test/logs/periodic-ci-operator-framework-operator-lifecycle-managment-rhoperator-metric-e2e-aws-olm-release-4.4-daily/\"" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "RT1xSMJ40ewc", + "colab": { + "base_uri": "https://localhost:8080/" + }, + "outputId": "5b979c6b-1fb2-441f-e09a-d776a072d3cf" + }, + "source": [ + "# Web scraping \n", + "# BeautifulSoup for web scraping\n", + "#url core needed to pull\n", + "website = \"https://gcsweb-ci.apps.ci.l2s4.p1.openshiftapps.com\"\n", + "\n", + "base = base15\n", + "ending = \"build-log.txt\"\n", + "finished = \"finished.json\"\n", + "page = requests.get(base) \n", + "data = page.text\n", + "soup = BeautifulSoup(data)\n", + "links = []\n", + "for link in soup.find_all('a'):\n", + " links.append(link.get('href'))\n", + "links = links[1:-1]\n", + "\n", + "final_array = []\n", + "labels_link = []\n", + "# create array of urls\n", + "for x in range(len(links)):\n", + " final_array.append(str(website) + str(links[x]) + str(ending))\n", + " labels_link.append(str(website) + str(links[x]) + str(finished))\n", + "\n", + "# pull all urls logs and store in 2-d array where array_of_logs[x] is a build-log file and \n", + "# array_of_logs[x][y] is an individual log line split by new line\n", + "\n", + "array_of_logs1 = []\n", + "for x in range(len(final_array)):\n", + " page = urlopen(final_array[x])\n", + " html_bytes = page.read()\n", + " array_of_logs1.append(str(html_bytes).split('\\\\n'))\n", + "\n", + "print(len(array_of_logs1))" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "490\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "IgNDOUFBG4zX", + "outputId": "d7251cab-a0a4-4d43-c207-2ac948d40b3d" + }, + "source": [ + "# Web scraping \n", + "# BeautifulSoup for web scraping\n", + "#url core needed to pull\n", + "website = \"https://gcsweb-ci.apps.ci.l2s4.p1.openshiftapps.com\"\n", + "\n", + "base = base16\n", + "ending = \"build-log.txt\"\n", + "finished = \"finished.json\"\n", + "page = requests.get(base) \n", + "data = page.text\n", + "soup = BeautifulSoup(data)\n", + "links = []\n", + "for link in soup.find_all('a'):\n", + " links.append(link.get('href'))\n", + "links = links[1:-1]\n", + "\n", + "final_array = []\n", + "labels_link2 = []\n", + "# create array of urls\n", + "for x in range(len(links)):\n", + " final_array.append(str(website) + str(links[x]) + str(ending))\n", + " labels_link2.append(str(website) + str(links[x]) + str(finished))\n", + "\n", + "# pull all urls logs and store in 2-d array where array_of_logs[x] is a build-log file and \n", + "# array_of_logs[x][y] is an individual log line split by new line\n", + "\n", + "array_of_logs2 = []\n", + "for x in range(len(final_array)):\n", + " page = urlopen(final_array[x])\n", + " html_bytes = page.read()\n", + " array_of_logs2.append(str(html_bytes).split('\\\\n'))\n", + "\n", + "print(len(array_of_logs2))" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "247\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "bu6M41HEHbHm", + "outputId": "91c0b7eb-c71c-4675-f3a1-867669ad40c4" + }, + "source": [ + "# Web scraping \n", + "# BeautifulSoup for web scraping\n", + "#url core needed to pull\n", + "website = \"https://gcsweb-ci.apps.ci.l2s4.p1.openshiftapps.com\"\n", + "\n", + "base = base17\n", + "ending = \"build-log.txt\"\n", + "finished = \"finished.json\"\n", + "page = requests.get(base) \n", + "data = page.text\n", + "soup = BeautifulSoup(data)\n", + "links = []\n", + "for link in soup.find_all('a'):\n", + " links.append(link.get('href'))\n", + "links = links[1:-1]\n", + "\n", + "final_array = []\n", + "labels_link3 = []\n", + "# create array of urls\n", + "for x in range(len(links)):\n", + " final_array.append(str(website) + str(links[x]) + str(ending))\n", + " labels_link3.append(str(website) + str(links[x]) + str(finished))\n", + "\n", + "# pull all urls logs and store in 2-d array where array_of_logs[x] is a build-log file and \n", + "# array_of_logs[x][y] is an individual log line split by new line\n", + "\n", + "array_of_logs3 = []\n", + "for x in range(len(final_array)):\n", + " page = urlopen(final_array[x])\n", + " html_bytes = page.read()\n", + " array_of_logs3.append(str(html_bytes).split('\\\\n'))\n", + "\n", + "print(len(array_of_logs3))" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "182\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "LEvrmTCnTu-S", + "colab": { + "base_uri": "https://localhost:8080/" + }, + "outputId": "29bb768b-0866-4f39-84f2-c73361e0bb40" + }, + "source": [ + "array_of_logs = array_of_logs1 #+ array_of_logs2 #+ array_of_logs3\n", + "print(len(array_of_logs))" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "490\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "WGNoRQkn7j3E" + }, + "source": [ + "# IMPORTANT\n", + "\n", + "Run this cell below a few times in a row in order for it to completely remove all the necessary things it is supposed to remove." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "JsfDoHsxQmqH", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 232 + }, + "outputId": "0d58766a-7484-4d57-fdd7-1dc32fe16f62" + }, + "source": [ + "\n", + "for i in range(len(array_of_logs)):\n", + " # removing newline characters\n", + " array_of_logs[i] = str(array_of_logs[i]).replace('\\\\n', ' ')\n", + " \n", + " # removes leading 'b from log\n", + " array_of_logs[i] = array_of_logs[i][2:]" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "error", + "ename": "NameError", + "evalue": "ignored", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0;32mfor\u001b[0m \u001b[0mi\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0marray_of_logs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3\u001b[0m \u001b[0;31m# removing newline characters\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0marray_of_logs\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mi\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mstr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0marray_of_logs\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mi\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mreplace\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'\\\\n'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m' '\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mNameError\u001b[0m: name 'array_of_logs' is not defined" + ] + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "OqeBizbVQn6m" + }, + "source": [ + "This code cell above removes newline characters and leading byte signature" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "heDQxXYAQzcU" + }, + "source": [ + "

Assigning Labels to Logs

" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "nX15zcw5v8_z", + "colab": { + "base_uri": "https://localhost:8080/" + }, + "outputId": "b072cc2f-d38c-4f5a-dabe-10ac71f41793" + }, + "source": [ + "labels= []\n", + "index = 0\n", + "to_remove = []\n", + "\n", + "\n", + "for x in range(len(labels_link)):\n", + " page = urlopen(labels_link[x])\n", + " try:\n", + " data = json.load(page) \n", + " except:\n", + " continue\n", + " labels.append(data[\"result\"])\n", + " index += 1\n", + "\n", + "# for x in range(len(labels_link2)):\n", + "# page = urlopen(labels_link2[x])\n", + "# try:\n", + "# data = json.load(page)\n", + "# labels.append(data[\"result\"])\n", + "# except:\n", + "# to_remove.append(index)\n", + "# continue\n", + "# index += 1\n", + "\n", + "# for x in range(len(labels_link3)):\n", + "# page = urlopen(labels_link3[x])\n", + "# try:\n", + "# data = json.load(page)\n", + "# labels.append(data[\"result\"])\n", + "# except:\n", + "# to_remove.append(index)\n", + "# continue\n", + "# index += 1\n", + "\n", + "\n", + "for i in range(len(array_of_logs)):\n", + " if i in to_remove:\n", + " array_of_logs[i] = None\n", + "\n", + "array_of_logs = [log for log in array_of_logs if log != None]\n", + "print(len(labels))" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "text": [ + "489\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "WflHVjf8LQuc", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 181 + }, + "outputId": "63dc2308-b86e-4c23-a59a-d66b6e089d47" + }, + "source": [ + "with open(\"/content/drive/MyDrive/RedHat_BU/log/log_file_5.ob\", 'wb') as fp:\n", + " pickle.dump(array_of_logs,fp)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "error", + "ename": "FileNotFoundError", + "evalue": "ignored", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mFileNotFoundError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;32mwith\u001b[0m \u001b[0mopen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"/content/drive/MyDrive/RedHat_BU/log/log_file_5.ob\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'wb'\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mfp\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0mpickle\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdump\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0marray_of_logs\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mfp\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mFileNotFoundError\u001b[0m: [Errno 2] No such file or directory: '/content/drive/MyDrive/RedHat_BU/log/log_file_5.ob'" + ] + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "uwk_jjWOR8rs" + }, + "source": [ + "with open(\"/content/drive/MyDrive/RedHat_BU/label/label_file_5.ob\", 'wb') as fp:\n", + " pickle.dump(labels,fp)" + ], + "execution_count": null, + "outputs": [] + } + ] +} \ No newline at end of file