Before I was using lightstep/opentelemetry-exporter-js, I can use my own exporters and Lightstep exporter at same time.
import { CollectorTraceExporter } from '#opentelemetry/exporter-collector';
import { NodeTracerProvider } from '#opentelemetry/node';
import { BatchSpanProcessor, ConsoleSpanExporter } from '#opentelemetry/tracing';
import { LightstepExporter } from 'lightstep-opentelemetry-exporter';
const initTracer = () => {
const serviceName = 'server-trace-service';
const tracerProvider = new NodeTracerProvider({
plugins: {
http: {
enabled: true,
path: '#opentelemetry/plugin-http',
},
},
});
tracerProvider.addSpanProcessor(new BatchSpanProcessor(new ConsoleSpanExporter()));
tracerProvider.addSpanProcessor(
new BatchSpanProcessor(
new CollectorTraceExporter({
serviceName,
})
)
);
tracerProvider.addSpanProcessor(
new BatchSpanProcessor(
new LightstepExporter({
serviceName,
token: 'myToken',
})
)
);
tracerProvider.register();
};
However, just saw lightstep/opentelemetry-exporter-js is deprecated and replaced by lightstep/otel-launcher-node.
I checked the source code of it and the demo, it looks like it is a "framework" on top of OpenTelemetry.
const {
lightstep,
opentelemetry,
} = require('lightstep-opentelemetry-launcher-node');
const sdk = lightstep.configureOpenTelemetry({
accessToken: 'YOUR ACCESS TOKEN',
serviceName: 'locl-ex',
});
sdk.start().then(() => {
const tracer = opentelemetry.trace.getTracer('otel-node-example');
const span = tracer.startSpan('test-span');
span.end();
opentelemetry.trace.getTracerProvider().getActiveSpanProcessor().shutdown();
});
Is it possible to simply use it as one of OpenTelemetry exporters?
lightstep-opentelemetry-launcher-node basically bundles the required things for you for easier configuration so this is not an exporter. If you were to simply replace the "LightstepExporter" with "OpenTelemetry Collector Exporter" in your code you can simply do this
import { CollectorTraceExporter } from '#opentelemetry/exporter-collector';
tracerProvider.addSpanProcessor(
new BatchSpanProcessor(
new CollectorTraceExporter({
url: 'YOUR_DIGEST_URL',
headers: {
'Lightstep-Access-Token': 'YOUR_TOKEN'
}
})
)
);
The default YOUR_DIGETS_URL from lightstep/otel-launcher-node is https://ingest.lightstep.com:443/api/v2/otel/trace
Related
I'm using Bootstrap vue table with contentful's API and could use some help with my code. I'm attempting to use a for loop to iterate over an array and get the property values. The console.info(episodes); call prints out each iteration for the var episodes, but now how do I bind this to my variable episodes. Using return only returns one result even outside of the for each loop. Any help or suggestions on another implementation is greatly appreciated. Full Template below.
<template>
<div>
<h1>Bootstrap Table</h1>
<b-table striped responsive hover :items="episodes" :fields="fields"></b-table>
</div>
</template>
<style>
</style>
<script>
import axios from "axios";
// Config
import config from "config";
// Vuex
import store from "store";
import { mapGetters, mapActions } from "vuex";
// Services
import { formatEntry } from "services/contentful";
// Models
import { entryTypes } from "models/contentful";
// UI
import UiEntry from "ui/Entry";
import UiLatestEntries from "ui/LatestEntries";
const contentful = require("contentful");
const client = contentful.createClient({
space: "xxxx",
environment: "staging", // defaults to 'master' if not set
accessToken: "xxxx"
});
export default {
name: "contentful-table",
data() {
return {
fields: [
{
key: "category",
sortable: true
},
{
key: "episode_name",
sortable: true
},
{
key: "episode_acronym",
sortable: true
},
{
key: "version",
sortable: true
}
],
episodes: []
};
},
mounted() {
return Promise.all([
// fetch the owner of the blog
client.getEntries({
content_type: "entryWebinar",
select: "fields.title,fields.description,fields.body,fields.splash"
})
])
.then(response => {
// console.info(response[0].items);
return response[0].items;
})
.then(response => {
this.episodes = function() {
var arrayLength = response.length;
var episodes = [];
for (let i = 0; i < arrayLength; i++) {
// console.info(response[i].fields.title + response[i].fields.splash + response[i].fields.description + response[i].fields.body );
var episodes = [
{
category: response[i].fields.title,
episode_name: response[i].fields.splash,
episode_acronym: response[i].fields.description,
version: response[i].fields.body
}
];
// episodes.forEach(category => episodes.push(category));
console.info(episodes);
}
return episodes;
};
})
.catch(console.error);
}
};
</script>
You can use the map method on the response array to return all the elements.
In your current example you keep re-setting the episodes variable, instead of the push() you actually want to do. The map method is still a more elegant way to solve your problem.
this.episodes = response.map((item) => {
return {
category: item.fields.title,
episode_name: items.fields.splash,
episode_acronym: item.fields.description,
version: item.fields.body
}
})
You can update the last then to match the last then below
]).then(response => {
return response[0].items;
})
.then((response) => {
this.episodes = response.map((item) => {
return {
category: item.fields.title,
episode_name: items.fields.splash,
episode_acronym: item.fields.description,
version: item.fields.body
};
});
})
.catch(console.error)
You do have an unnecessary second then, but I left it there so that you could see what I am replacing.
I have a pretty simple requirement to click on a phone number hyperlink and have my web-app open the AWS connect soft-phone dialer with the selected number, ready for the person to press the "call button"
I have enabled an AWS connect account and I am hosting a custom CCP site via an S3 bucket (as illustrated here)
My plan is to initiate a link to the CCP page and embed a URL Search Param
"?number=04125412,customTag=helloWorld"
I have used this code on the CCP Page
Also, within the index page, I add some code to receive the input params:
<script>
var urlParams = new URLSearchParams(window.location.search);
console.log(urlParams.get('number')); //the phone number for the dialer
console.log(urlParams.get('customTag')); // the call notes for the CTR custom Attributes
</script>
I Am struggling to understand how I can interact with A: the Dialer to pre-fill the number and B: to post custom attributes to the AWS contact record during the call.
Any help would be appreciated.
I set this up in my React application but you should be able to repurpose for your needs
import React from "react";
import {connect} from 'react-redux'
import Button from "components/CustomButtons/Button.jsx";
import {receiveCallAttr, initCall, callFlow} from 'store/apps/AppSettings/actions';
class AmazonConnect extends React.Component {
constructor(props) {
super(props);
this.state = {
active:false,
reloadAttempts:0,
activeCall:{},
cip:false,
agentQueueNumber:"xxxxxxxxxx",
recordingQueueNumber:"xxxxxxxxxx"
};
this.awsConnect = this.awsConnect.bind(this)
this.loginWindow = this.loginWindow.bind(this);
this.activeWindow = this.activeWindow.bind(this);
this.initCall = this.initCall.bind(this)
this.initContact = this.initContact.bind(this)
this.redirect = this.redirect.bind(this)
}
componentWillReceiveProps(newProps){
const {AppSettings, initCall, callFlow} = newProps
const {cip, active} = this.state
if( active && !cip){
this.setState({activeCall: AppSettings.call})
if(AppSettings.call.number){
console.log("init call")
this.initCall(AppSettings.call.number)
initCall({})
}
else{
console.log("Invalid Phone number")
}
if( AppSettings.flow !== "" ){
this.setState({activeFlow: AppSettings.flow})
this.initCallFlow(AppSettings.flow)
callFlow("")
}
}
}
initCallFlow = flow => new Promise((res, rej) => {
if(this.contact){
console.log(this.contact)
let endpoint;
switch(flow){
case "agentQueue":
endpoint = window.connect.Endpoint.byPhoneNumber(this.state.agentQueueNumber);
this.contact.addConnection(endpoint, {
success: function() {
this.contact.conferenceConnections({
success: function() {
console.log("confrence success")
res("successfullly init ssn flow")
},
failure: function() {
console.log("confrence failure")
res("successfullly init ssn flow")
}
});
},
failure: function() {
rej("failed to init ssn flow")
}
});
break
case "recordingQueue":
endpoint = window.connect.Endpoint.byPhoneNumber(this.state.recordingQueueNumber);
this.contact.addConnection(endpoint, {
success: function() {
res("successfullly init recording flow")
},
failure: function() {
rej("failed to init recording flow")
}
});
break
default:
res()
break
}
}
else{
rej("no contact available")
}
})
awsConnect = () => new Promise((res, rej) => {
window.connect.core.initCCP(document.getElementById("softPhone"), {
ccpUrl: process.env.REACT_APP_AWS_CONNECT_URL, /*REQUIRED*/
loginPopup: true, /*optional, default TRUE*/
softphone: { /*optional*/
disableRingtone: false, /*optional*/
allowFramedSoftphone: true
}
});
this.bus = window.connect.core.getEventBus();
this.bus.subscribe(window.connect.AgentEvents.INIT, (agent) => {
this.activeWindow()
});
this.bus.subscribe(window.connect.EventType.TERMINATED, () => {
console.log("TERMINATED")
this.setState({cip:false})
this.logout()
});
this.bus.subscribe(window.connect.EventType.AUTH_FAIL, () => {
console.log("AUTH_FAIL")
this.logout()
})
window.connect.agent(function(agent) {
const w = window.open('', window.connect.MasterTopics.LOGIN_POPUP);
if (w) {
w.close()
}
});
window.connect.contact((contact) => {
this.contact = contact
const {receiveCallAttr} = this.props
try{
var attr = contact.getAttributes()
attr.active = true
console.log(attr)
receiveCallAttr(attr)
this.redirect()
}
catch(err){
console.log(err)
}
contact.onEnded(() => {
console.log("call ended")
receiveCallAttr({active:false})
this.setState({cip:false})
this.contact = null
})
});
res()
})
initContact = () => {
this.setState({cip:false})
}
redirect = () => {
const {location, auth, history} = this.props
switch(auth.user.type){
case "Agent":
if(location.pathname !== "/agent/management"){
history.push({
pathname: '/agent/management',
search: '',
state: {}
})
}
break;
case "Service":
//handle redirect to service page
if(location.pathname !== "/service/dashboard"){
history.push({
pathname: "/service/dashboard",
search: '',
state: {}
})
}
break;
default:
break
}
}
initCall = (phone) => {
this.initContact()
window.connect.agent(function(agent) {
const endpoint = window.connect.Endpoint.byPhoneNumber(phone)
agent.connect(endpoint , {
queueARN : process.env.CONNECT_QUEUE_ARN,
success : function(){
console.log("Success call!!!!!!")
},
failure : function(){
console.log("Call failed!!!!!!!")
}
});
});
}
logout(){
this.setState({cip:false})
this.loginWindow()
this.agent = null
this.contact = null
window.connect.core.terminate();
window.connect.core.client = new window.connect.NullClient();
window.connect.core.masterClient = new window.connect.NullClient();
window.connect.core.eventBus = new window.connect.EventBus();
window.connect.core.initialized = false;
this.bus = false;
var myNode = document.getElementById("softPhone")
while (myNode.firstChild) {
myNode.removeChild(myNode.firstChild);
}
}
componentWillUnmount() {
console.log("terminating aws connect session")
this.logout()
}
loginWindow(){
this.setState({active:false})
}
activeWindow(){
this.setState({active:true})
}
render() {
const displaylogin = this.state.active? "none":"block";
const displayConnect = this.state.active? "block":"none";
return (
<div>
<Button color={"rose"} onClick={this.awsConnect} style={{display:displaylogin, width:320}}>Login to AWS Connect</Button>
<div id="softPhone" style={{height:465,width:320, display:displayConnect}}>
</div>
</div>
);
}
}
function mapStateToProps(state){
return state
}
export default connect(mapStateToProps, {receiveCallAttr, initCall, callFlow})(AmazonConnect);
The previous answer by Ethan Harris helped me to reach the solution, but to distill it to allow a link to dial a number. You find the ARN in the Amazon Connect UI here:
Using the ARN copied from the Connect UI, this function seems to work for automating dialing a number. This took way more effort to figure out than I ever expected.
function dial_number(phone) {
connect.agent(function (agent) {
agent.connect(connect.Endpoint.byPhoneNumber(phone),
{
queueARN: arn
});
});
}
Subscriptions with Nexus are undocumented but I searched Github and tried every example in the book. It's just not working for me.
I have cloned Prisma2 GraphQL boilerplate project & my files are as follows:
prisma/schema.prisma
datasource db {
provider = "sqlite"
url = "file:dev.db"
default = true
}
generator photon {
provider = "photonjs"
}
generator nexus_prisma {
provider = "nexus-prisma"
}
model Pokemon {
id String #default(cuid()) #id #unique
number Int #unique
name String
attacks PokemonAttack?
}
model PokemonAttack {
id Int #id
special Attack[]
}
model Attack {
id Int #id
name String
damage String
}
src/index.js
const { GraphQLServer } = require('graphql-yoga')
const { join } = require('path')
const { makeSchema, objectType, idArg, stringArg, subscriptionField } = require('#prisma/nexus')
const Photon = require('#generated/photon')
const { nexusPrismaPlugin } = require('#generated/nexus-prisma')
const photon = new Photon()
const nexusPrisma = nexusPrismaPlugin({
photon: ctx => ctx.photon,
})
const Attack = objectType({
name: "Attack",
definition(t) {
t.model.id()
t.model.name()
t.model.damage()
}
})
const PokemonAttack = objectType({
name: "PokemonAttack",
definition(t) {
t.model.id()
t.model.special()
}
})
const Pokemon = objectType({
name: "Pokemon",
definition(t) {
t.model.id()
t.model.number()
t.model.name()
t.model.attacks()
}
})
const Query = objectType({
name: 'Query',
definition(t) {
t.crud.findManyPokemon({
alias: 'pokemons'
})
t.list.field('pokemon', {
type: 'Pokemon',
args: {
name: stringArg(),
},
resolve: (parent, { name }, ctx) => {
return ctx.photon.pokemon.findMany({
where: {
name
}
})
},
})
},
})
const Mutation = objectType({
name: 'Mutation',
definition(t) {
t.crud.createOnePokemon({ alias: 'addPokemon' })
},
})
const Subscription = subscriptionField('newPokemon', {
type: 'Pokemon',
subscribe: (parent, args, ctx) => {
return ctx.photon.$subscribe.pokemon()
},
resolve: payload => payload
})
const schema = makeSchema({
types: [Query, Mutation, Subscription, Pokemon, Attack, PokemonAttack, nexusPrisma],
outputs: {
schema: join(__dirname, '/schema.graphql')
},
typegenAutoConfig: {
sources: [
{
source: '#generated/photon',
alias: 'photon',
},
],
},
})
const server = new GraphQLServer({
schema,
context: request => {
return {
...request,
photon,
}
},
})
server.start(() => console.log(`🚀 Server ready at http://localhost:4000`))
The related part is the Subscription which I don't know why it's not working or how it's supposed to work.
I searched Github for this query which results in all projects using Subscriptions.
I also found out this commit in this project to be relevant to my answer. Posting the related code here for brevity:
import { subscriptionField } from 'nexus';
import { idArg } from 'nexus/dist/core';
import { Context } from './types';
export const PollResultSubscription = subscriptionField('pollResult', {
type: 'AnswerSubscriptionPayload',
args: {
pollId: idArg(),
},
subscribe(_: any, { pollId }: { pollId: string }, context: Context) {
// Subscribe to changes on answers in the given poll
return context.prisma.$subscribe.answer({
node: { poll: { id: pollId } },
});
},
resolve(payload: any) {
return payload;
},
});
Which is similar to what I do. But they do have AnswerSubscriptionPayload & I don't get any generated type that contains Subscription in it.
How do I solve this? I think I am doing everything right but it's still not working. Every example on GitHub is similar to above & even I am doing the same thing.
Any suggestions?
Edit: Subscriptions aren't implemented yet :(
I seem to have got this working despite subscriptions not being implemented. I have a working pubsub proof of concept based off the prisma2 boilerplate and Ben Awad's video tutorial https://youtu.be/146AypcFvAU . Should be able to get this up and running with redis and websockets to handle subscriptions until the prisma2 version is ready.
https://github.com/ryanking1809/prisma2_subscriptions
Subscriptions aren't implemented yet.
I've opened up an issue to track it.
I'll edit this answer as soon as it's implemented in Prisma 2.
I am new to Vuex and Nuxt.
I would like to use vuex to fetch dropbox filestructure and store them.
Here is my code. the console.log seems to work fine. it prints out something like below.
But the structure still turns out to be [] when i use in index.vue
[ { '.tag': 'file',
name: 'Document.docx',
path_lower: '/posts/document.docx',
path_display: '/posts/Document.docx',
id: 'id:H_6Dhj1r7cEAAAAAAAAXlQ',
client_modified: '2018-09-02T14:23:05Z',
server_modified: '2018-09-02T14:23:06Z',
rev: '5e5cab150',
size: 11366,
content_hash: 'd26bb0382752820694d31f42e82e31ef72bed683b90e02952ea09125264d4124' },
{ '.tag': 'file',
name: '2013-5-17-first-post.md',
path_lower: '/posts/2013-5-17-first-post.md',
path_display: '/posts/2013-5-17-first-post.md',
id: 'id:H_6Dhj1r7cEAAAAAAAAXlg',
client_modified: '2018-09-02T14:25:38Z',
server_modified: '2018-09-02T14:25:38Z',
rev: '6e5cab150',
size: 136,
content_hash: '3b8d60de425e8280d55e45d7359cd3290abc5bc3b0bb6831b09a6da0d3cb6a12' } ]
the code is like below
import "isomorphic-fetch"
import {
Dropbox
} from "dropbox";
import {
DropboxTeam
} from "dropbox";
export const state = () => ({
structure: []
});
export const mutations = {
setStucture(state, structure) {
state.structure = structure.slice();
console.log(state.structure);
// console.log(structure.slice());
}
};
export const actions = {
async nuxtServerInit({ commit }) {
let accessToken = "XXXXX"
let dropbox = new Dropbox({
accessToken: accessToken
});
dropbox.filesListFolder({path: '/posts'})
.then(response => {
const structure = response.entries;
commit("setStucture", structure);
})
.catch(error => {
console.log(error);
});
}
};
Can I get some help. Thank you!
add await to dropbox.filesListFolder({path: '/posts'}) like below turned out to be the right answer.
await dropbox.filesListFolder({path: '/posts'})
I am trying to get the following example working:
https://github.com/typeorm/javascript-example/tree/master/src/app3-es6
I am running into the following error:
Error
at new RepositoryNotFoundError (...\node_modules\typeorm\connection\error\RepositoryNotFoundError.js:24:23)
at Connection.findRepositoryAggregator (...\node_modules\typeorm\connection\Connection.js:513:19)
at Connection.getRepository (...\node_modules\typeorm\connection\Connection.js:405:21)
at ...\index.js:27:37
name: 'RepositoryNotFoundError',
message: 'No repository for "Post" was found. Looks like this entity is not registered in current "default" connection?'
here is index.js
const typeorm = require("typeorm"); // import * as typeorm from "typeorm";
const Post = require("./model/Post"); // import {Post} from "./model/Post";
// import Post from './model/Post.js';
const Category = require("./model/Category"); // import {Category} from "./model/Category";
typeorm.createConnection({
driver: {
type: "oracle",
host: "localhost",
port: 1521,
username: "uname",
password: "pwd",
sid: "dev"
},
entities: [
__dirname + "/entity/*.js"
],
autoSchemaSync: true
}).then(function (connection) {
console.log(connection);
let post = new Post.Post();
post.title = "Control flow based type analysis";
post.text = "TypeScript 2.0 implements a control flow-based type analysis for local variables and parameters.";
post.categories = [new Category.Category(0, "TypeScript"), new Category.Category(0, "Programming")];
let postRepository = connection.getRepository(Post.Post);
postRepository.persist(post)
.then(function(savedPost) {
console.log("Post has been saved: ", savedPost);
console.log("Now lets load all posts: ");
return postRepository.find();
})
.then(function(allPosts) {
console.log("All posts: ", allPosts);
});
}).catch(function(error) {
console.log("Error: ", error);
});
Post.js in /model/
/*export */ class Post {
constructor(id, title, text, categories) {
this.id = id;
this.title = title;
this.text = text;
this.categories = categories;
}
}
module.exports = {
Post: Post
};
Category.js
/*export */ class Category {
constructor(id, name) {
this.id = id;
this.name = name;
}
}
module.exports = {
Category: Category
};
PostSchema.js in /entity/
const Post = require("../model/Post"); // import {Post} from "../model/Post";
const Category = require("../model/Category"); // import {Category} from "../model/Category";
const PostSchema = {
target: Post,
columns: {
id: {
primary: true,
type: "int",
generated: true
},
title: {
type: "string"
},
text: {
type: "text"
}
},
relations: {
categories: {
target: Category,
type: "many-to-many",
joinTable: true,
cascadeInsert: true
}
}
};
module.exports = {
PostSchema: PostSchema
};
CategorySchema.js
const Category = require("../model/Category"); // import {Category} from "../model/Category";
const CategorySchema = {
target: Category,
columns: {
id: {
primary: true,
type: "int",
generated: true
},
name: {
type: "string"
}
}
};
module.exports = {
CategorySchema: CategorySchema
};
i dont know what i am doing wrong
It looks like your entity import is not working. If you import via the wildcard:
entities: [
__dirname + "/entity/*.js"
],`
Make sure your model is compiled to js. You also could just import
createConnection({
...,
entities: [
Post,
...
],}).then(...)
For those who are using typescript and experience this problem: Be reminded that you need to include both ts and js file suffixes when specifying the entities-path:
ts used when locally running with ts-node
js used when having
built for production via tsc.
Code:
import * as path from 'path';
// ...
entities: [
// assuming _dirname is your project root
path.resolve(__dirname, '**/*.entity{.ts,.js}'),
],
I had the same problem for months and finally figured out what I was doing wrong.
When you import Entities, make sure the file names are EXACTLY matching. It's not going to throw any errors, but during the run time, it's going to throw the above error.
Ex. In the entity or model classes, if we import like this,
import { FooClass } from "./foo-Class.model";
it's different from
import { FooClass } from "./foo-class.model";
It won't show any errors, but when you try to call the table, it will show the exact same error.
I had the same problem. None of the solutions worked for me. After much debugging I figured out that you'll receive this error if your connection is closed.
So if you are facing this error, make sure your connection is not closed.
try {
connection = getConnection(config.name)
//after adding this if block, I no longer received this error
if (!connection.isConnected) {
await connection.connect();
}
} catch(err) {
connection = await createConnection(config);
}
If it is closed, connect it again.