1660791733
In this video We will teach you guys how to configure TypeScript in a nodejs and express api.
Commands:
- sudo yarn global add typescript
- yarn add express nodemon ts-node @types/express @types/node typescript
- tsc --init
Code: https://github.com/machadop1407/typescript-express-config
Subscribe: https://www.youtube.com/c/PedroTechnologies/featured
1660783860
Node Application Metrics monitoring and profiling agent
Node Application Metrics instruments the Node.js runtime for performance monitoring, providing the monitoring data via an API. Additionally the data can be visualized by using the Node Application Metrics Dashboard.
The data can also be visualized in Eclipse using the IBM Monitoring and Diagnostics Tools - Health Center client. Profiling data is available in Health Center, but is not yet available in the Dashboard. See https://www.ibm.com/developerworks/java/jdk/tools/healthcenter/ for more details.
Node Application Metrics provides the following built-in data collection sources:
Source | Description |
---|---|
Environment | Machine and runtime environment information |
CPU | Process and system CPU |
Memory | Process and system memory usage |
GC | Node/V8 garbage collection statistics |
Event Loop | Event loop latency information |
Loop | Event loop timing metrics |
Function profiling | Node/V8 function profiling (disabled by default) |
HTTP | HTTP request calls made of the application |
HTTP Outbound | HTTP requests made by the application |
socket.io | WebSocket data sent and received by the application |
LevelDB | LevelDB queries made by the application |
MySQL | MySQL queries made by the application |
MongoDB | MongoDB queries made by the application |
PostgreSQL | PostgreSQL queries made by the application |
MQTT | MQTT messages sent and received by the application |
MQLight | MQLight messages sent and received by the application |
Memcached | Data that is stored or manipulated in Memcached |
OracleDB | OracleDB queries made by the application |
Oracle | Oracle queries made by the application |
StrongOracle | StrongOracle database queries made by the application |
Redis | Redis commands issued by the application |
Riak | Riak methods called by the application |
Request tracking | A tree of application requests, events and optionally trace (disabled by default) |
Function trace | Tracing of application function calls that occur during a request (disabled by default) |
Our testing has shown that the performance overhead in terms of processing is minimal, adding less than 0.5 % to the CPU usage of your application. The additional memory required is around 20 MB to gather information about your system and application.
We gathered this information by monitoring the sample application Acme Air. We used MongoDB as our datastore and used JMeter to drive load though the program. We have performed this testing with Node.js version 6.10.3
Appmetrics uses node-gyp
to compile and build local binary libraries to enhance execution performance. If the following compilation and build logs contain errors, make sure you have the node-gyp pre-requisites installed (https://github.com/nodejs/node-gyp#installation). If you have them and the build still had errors, see if there are any related issues at https://github.com/RuntimeTools/appmetrics/issues). If there aren't, feel free to open a new issue to report the bug.
You can get Node Application Metrics from 3 different places:
npm install appmetrics
. Requires a compiler)Node Application Metrics can be configured in two ways, by using the configuration file described below or via a call to configure(options).
Node Application Metrics comes with a configuration file inside the module installation directory (.../node_modules/appmetrics/appmetrics.properties
). This can be used to configure connection options, logging and data source options.
Node Application Metrics will attempt to load appmetrics.properties
from one of the following locations (in order):
The default configuration has minimal logging enabled, will attempt to send data to a local MQTT server on the default port and has method profiling disabled.
Many of the options provide configuration of the Health Center core agent library and are documented in the Health Center documentation: Health Center configuration properties.
The following options are specific to appmetrics:
com.ibm.diagnostics.healthcenter.data.profiling=[off|on]
Specifies whether method profiling data will be captured. The default value is off
. This specifies the value at start-up; it can be enabled and disabled dynamically as the application runs, either by a monitoring client or the API.In previous versions appmetrics came with an executable, node-hc
, which could be used instead of the node
command to run your application and load and start appmetrics. This has been removed in version 4.0.0, instead you can use:
$ node --require appmetrics/start app.js
to preload and start appmetrics, or in Node.js from versions 8.0.0 and 6.12.0 onwards, use the NODE_OPTIONS environment variable:
$ export NODE_OPTIONS="--require appmetrics/start"
If you locally install this module with npm then you will additionally have access to the monitoring data via the appmetrics
API (see API Documentation).
To load appmetrics
and get the monitoring API object, add the following to the start-up code for your application:
var appmetrics = require('appmetrics');
var monitoring = appmetrics.monitor();
The call to appmetrics.monitor()
starts the data collection agent, making the data available via the API and to the Heath Center client via MQTT.
You should start your application using the node
command as usual (not node-hc
).
You must call require('appmetrics');
before the require statements for any npm modules you want to monitor. Appmetrics must be initialized first so that it can instrument modules for monitoring as they are loaded. If this is a problem due to the structure of your application you can require the module on the node command line by using -r or --require or by setting NODE_OPTIONS as described above to make sure it is pre-loaded.
Once you have loaded appmetrics you can then use the monitoring object to register callbacks and request information about the application:
monitoring.on('initialized', function (env) {
env = monitoring.getEnvironment();
for (var entry in env) {
console.log(entry + ':' + env[entry]);
};
});
monitoring.on('cpu', function (cpu) {
console.log('[' + new Date(cpu.time) + '] CPU: ' + cpu.process);
});
Not supported on z/OS
Connecting to the Health Center client requires the additional installation of a MQTT broker. The Node Application Metrics agent sends data to the MQTT broker specified in the appmetrics.properties
file or set via a call to configure(options). Installation and configuration documentation for the Health Center client is available from the Health Center documentation in IBM Knowledge Center.
Note that both the API and the Health Center client can be used at the same time and will receive the same data. Use of the API requires a local install and application modification (see Modifying your application to use the local installation).
Further information regarding the use of the Health Center client with Node Application Metrics can be found on the appmetrics wiki: Using Node Application Metrics with the Health Center client.
Sets various properties on the appmetrics monitoring agent. If the agent has already been started, this function does nothing.
options
(Object) key value pairs of properties and values to be set on the monitoring agent.Property name | Property value type | Property description |
---|---|---|
applicationID | string | Specifies a unique identifier for the mqtt connection |
mqtt | string['off'|'on'] | Specifies whether the monitoring agent sends data to the mqtt broker. The default value is 'on' |
mqttHost | string | Specifies the host name of the mqtt broker |
mqttPort | string['[0-9]*'] | Specifies the port number of the mqtt broker |
profiling | string['off'|'on'] | Specifies whether method profiling data will be captured. The default value is 'off' |
Starts the appmetrics monitoring agent. If the agent is already running this function does nothing.
Stops the appmetrics monitoring agent. If the agent is not running this function does nothing.
type
, config
)Enable data generation of the specified data type. Cannot be called until the agent has been started by calling start()
or monitor()
.
type
(String) the type of event to start generating data for. Values of eventloop
, profiling
, http
, http-outbound
, mongo
, socketio
, mqlight
, postgresql
, mqtt
, mysql
, redis
, riak
, memcached
, oracledb
, oracle
, strong-oracle
, requests
and trace
are currently supported. As trace
is added to request data, both requests
and trace
must be enabled in order to receive trace data.config
(Object) (optional) configuration map to be added for the data type being enabled. (see setConfig) for more information.The following data types are disabled by default: profiling
, requests
, trace
type
)Disable data generation of the specified data type. Cannot be called until the agent has been started by calling start()
or monitor()
.
type
(String) the type of event to stop generating data for. Values of eventloop
, profiling
, http
, mongo
, socketio
, mqlight
, postgresql
, mqtt
, mysql
, redis
, riak
, memcached
, oracledb
, oracle
, strong-oracle
, requests
and trace
are currently supported.type
, config
)Set the configuration to be applied to a specific data type. The configuration available is specific to the data type.
type
(String) the type of event to apply the configuration to.config
(Object) key value pairs of configurations to be applied to the specified event. The available configuration options are as follows:Type | Configuration key | Configuration Value |
---|---|---|
http | filters | (Array) of URL filter Objects consisting of:
|
requests | excludeModules | (Array) of String names of modules to exclude from request tracking. |
trace | includeModules | (Array) of String names for modules to include in function tracing. By default only non-module functions are traced when trace is enabled. |
advancedProfiling | threshold | (Number) millisecond run time of an event loop cycle that will trigger profiling |
type
, data
)Allows custom monitoring events to be added into the Node Application Metrics agent.
type
(String) the name you wish to use for the data. A subsequent event of that type will be raised, allowing callbacks to be registered for it.data
(Object) the data to be made available with the event. The object must not contain circular references, and by convention should contain a time
value representing the milliseconds when the event occurred.Not supported on z/OS Dumps the v8 heap via heapdump
. For more information, see https://github.com/bnoordhuis/node-heapdump/blob/master/README.md
Creates a Node Application Metrics agent client instance. This can subsequently be used to get environment data and subscribe to data events. This function will start the appmetrics monitoring agent if it is not already running.
Requests an object containing all of the available environment information for the running application. This will not contain all possible environment information until an 'initialized' event has been received.
Not supported on z/OS Emitted when a CPU monitoring sample is taken.
data
(Object) the data from the CPU sample:time
(Number) the milliseconds when the sample was taken. This can be converted to a Date using new Date(data.time)
.process
(Number) the percentage of CPU used by the Node.js application itself. This is a value between 0.0 and 1.0.system
(Number) the percentage of CPU used by the system as a whole. This is a value between 0.0 and 1.0.Emitted every 5 seconds, summarising sample based information of the event loop latency
data
(Object) the data from the event loop sample:time
(Number) the milliseconds when the event was emitted. This can be converted to a Date using new Date(data.time)
.latency.min
(Number) the shortest sampled latency, in milliseconds.latency.max
(Number) the longest sampled latency, in milliseconds.latency.avg
(Number) the average sampled latency, in milliseconds.Emitted when a garbage collection (GC) cycle occurs in the underlying V8 runtime.
data
(Object) the data from the GC sample:time
(Number) the milliseconds when the sample was taken. This can be converted to a Date using new Date(data.time)
.type
(String) the type of GC cycle, either:'M'
: MarkSweepCompact, aka "major"'S'
: Scavenge, aka "minor"'I'
: IncrementalMarking, aka "incremental" (only exists on node 5.x and greater)W'
: ProcessWeakCallbacks, aka "weakcb" (only exists on node 5.x and greater)size
(Number) the size of the JavaScript heap in bytes.used
(Number) the amount of memory used on the JavaScript heap in bytes.duration
(Number) the duration of the GC cycle in milliseconds.Emitted when all possible environment variables have been collected. Use appmetrics.monitor.getEnvironment()
to access the available environment variables.
Emitted every 5 seconds, summarising event tick information in time interval
data
(Object) the data from the event loop sample:count
(Number) the number of event loop ticks in the last interval.minimum
(Number) the shortest (i.e. fastest) tick in milliseconds.maximum
(Number) the longest (slowest) tick in milliseconds.average
(Number) the average tick time in milliseconds.cpu_user
(Number) the percentage of 1 CPU used by the event loop thread in user code the last interval. This is a value between 0.0 and 1.0.cpu_system
(Number) the percentage of 1 CPU used by the event loop thread in system code in the last interval. This is a value between 0.0 and 1.0.Emitted when a memory monitoring sample is taken.
data
(Object) the data from the memory sample:time
(Number) the milliseconds when the sample was taken. This can be converted to a Date using new Date(data.time)
.physical_total
(Number) the total amount of RAM available on the system in bytes.physical_used
(Number) the total amount of RAM in use on the system in bytes.physical_free
(Number) the total amount of free RAM available on the system in bytes.virtual
(Number) the memory address space used by the Node.js application in bytes.private
(Number) the amount of memory used by the Node.js application that cannot be shared with other processes, in bytes.physical
(Number) the amount of RAM used by the Node.js application in bytes.Emitted when a profiling sample is available from the underlying V8 runtime.
data
(Object) the data from the profiling sample:time
(Number) the milliseconds when the sample was taken. This can be converted to a Date using new Date(data.time)
.functions
(Array) an array of functions that ran during the sample. Each array entry consists of:self
(Number) the ID for this function.parent
(Number) the ID for this function's caller.name
(String) the name of this function.file
(String) the file in which this function is defined.line
(Number) the line number in the file.count
(Number) the number of samples for this function.Emitted when a HTTP/HTTPS request is made of the application.
data
(Object) the data from the HTTP(S) request:time
(Number) the milliseconds when the request was made. This can be converted to a Date using new Date(data.time)
.method
(String) the HTTP(S) method used for the request.url
(String) the URL on which the request was made.duration
(Number) the time taken for the HTTP(S) request to be responded to in ms.header
(String) the response header for the HTTP(S) request.contentType
(String) the content type of the HTTP(S) request.requestHeader
(Object) the request header for HTTP(S) request.Emitted when the application makes an outbound HTTP/HTTPS request.
data
(Object) the data from the HTTP(S) request:time
(Number) the milliseconds when the request was made. This can be converted to a Date using new Date(data.time)
.method
(String) the HTTP(S) method used for the request.url
(String) the URL on which the request was made.contentType
(String) the HTTP(S) response content-type.statusCode
(String) the HTTP response status code.duration
(Number) the time taken for the HTTP(S) request to be responded to in ms.Emitted when a LevelDB query is made using the leveldown
module.
data
(Object) the data from the LevelDB query:time
(Number) the time in milliseconds when the LevelDB query was made. This can be converted to a Date using new Date(data.time)
.method
(String) The leveldown method being used.key
(Object) The key being used for a call to get
, put
or del
(Undefined for other methods)value
(Object) The value being added to the LevelDB database using the put
method (Undefined for other methods)opCount
(Number) The number of operations carried out by a batch
method (Undefined for other methods)duration
(Number) the time taken for the LevelDB query to be responded to in ms.Emitted when a function is called on the loopback-datasource-juggler
module
data
(Object) the data from the loopback-datasource-juggler event:time
(Number) the time in milliseconds when the event occurred. This can be converted to a Date using new Date(data.time)
method
(String) the function the juggler has executedduration
(Number) the time taken for the operation to complete.Emitted when a data is stored, retrieved or modified in Memcached using the memcached
module.
data
(Object) the data from the memcached event:time
(Number) the milliseconds when the memcached event occurred. This can be converted to a Date using new Date(data.time)
method
(String) the method used in the memcached client, eg set
, get
, append
, delete
, etc.key
(String) the key associated with the data.duration
(Number) the time taken for the operation on the memcached data to occur.Emitted when a MongoDB query is made using the mongodb
module.
data
(Object) the data from the MongoDB request:time
(Number) the milliseconds when the MongoDB query was made. This can be converted to a Date using new Date(data.time)
query
(String) the query made of the MongoDB database.duration
(Number) the time taken for the MongoDB query to be responded to in ms.method
(String) the executed method for the query, such as find, update.collection
(String) the MongoDB collection name.Emitted when a MQLight message is sent or received.
data
(Object) the data from the MQLight event:time
(Number) the time in milliseconds when the MQLight event occurred. This can be converted to a Date using new Date(data.time).clientid
(String) the id of the client.data
(String) the data sent if a 'send' or 'message', undefined for other calls. Truncated if longer than 25 characters.method
(String) the name of the call or event (will be one of 'send' or 'message').topic
(String) the topic on which a message is sent/received.qos
(Number) the QoS level for a 'send' call, undefined if not set.duration
(Number) the time taken in milliseconds.Emitted when a MQTT message is sent or received.
data
(Object) the data from the MQTT event:time
(Number) the time in milliseconds when the MQTT event occurred. This can be converted to a Date using new Date(data.time).method
(String) the name of the call or event (will be one of 'publish' or 'message').topic
(String) the topic on which a message is published or received.qos
(Number) the QoS level for the message.duration
(Number) the time taken in milliseconds.Emitted when a MySQL query is made using the mysql
module.
data
(Object) the data from the MySQL query:time
(Number) the milliseconds when the MySQL query was made. This can be converted to a Date using new Date(data.time)
.query
(String) the query made of the MySQL database.duration
(Number) the time taken for the MySQL query to be responded to in ms.Emitted when a query is executed using the oracle
module.
data
(Object) the data from the Oracle query:time
(Number) the milliseconds when the Oracle query was made. This can be converted to a Date using new Date(data.time)
.query
(String) the query made of the Oracle database.duration
(Number) the time taken for the Oracle query to be responded to in ms.Emitted when a query is executed using the oracledb
module.
data
(Object) the data from the OracleDB query:time
(Number) the milliseconds when the OracleDB query was made. This can be converted to a Date using new Date(data.time)
.query
(String) the query made of the OracleDB database.duration
(Number) the time taken for the OracleDB query to be responded to in ms.Emitted when a PostgreSQL query is made to the pg
module.
data
(Object) the data from the PostgreSQL query:time
(Number) the milliseconds when the PostgreSQL query was made. This can be converted to a Date using new Date(data.time)
.query
(String) the query made of the PostgreSQL database.duration
(Number) the time taken for the PostgreSQL query to be responded to in ms.Emitted when a Redis command is sent.
data
(Object) the data from the Redis event:time
(Number) the time in milliseconds when the redis event occurred. This can be converted to a Date using new Date(data.time).cmd
(String) the Redis command sent to the server or 'batch.exec'/'multi.exec' for groups of command sent using batch/multi calls.duration
(Number) the time taken in milliseconds.Emitted when a Riak method is called using the basho-riak-client
module.
data
(Object) the data from the Riak event:time
(Number) the time in milliseconds when the riak event occurred. This can be converted to a Date using new Date(data.time).method
(String) the Riak method called.options
(Object) the options parameter passed to Riak.command
(Object) the command parameter used in the execute
method.query
(String) the query parameter used in the mapReduce
method.duration
(Number) the time taken in milliseconds.Emitted when WebSocket data is sent or received by the application using socketio.
data
(Object) the data from the socket.io request:time
(Number) the milliseconds when the event occurred. This can be converted to a Date using new Date(data.time)
.method
(String) whether the event is a broadcast
or emit
from the application, or a receive
from a client .event
(String) the name used for the event.duration
(Number) the time taken for event to be sent or for a received event to be handled.Emitted when a query is executed using the strong-oracle
module.
data
(Object) the data from the Strong Oracle query:time
(Number) the milliseconds when the Strong Oracle query was made. This can be converted to a Date using new Date(data.time)
.query
(String) the query made of the database.duration
(Number) the time taken for the Strong Oracle query to be responded to in ms.Requests are a special type of event emitted by appmetrics. All the probes named above can also create request events if requests are enabled. However requests are nested within a root incoming request (usually http). Request events are disabled by default.
data
(Object) the data from the request:time
(Number) the milliseconds when the request occurred. This can be converted to a Date using new Date(data.time)
.type
(String) The type of the request event. This is the name of the probe that sent the request data, e.g. http
, socketio
etc.name
(String) The name of the request event. This is the request task, eg. the url, or the method being used.request
(Object) the detailed data for the root request event:type
(String) The type of the request event. This is the name of the probe that sent the request data, e.g. http
, socketio
etc.name
(String) The name of the request event. This is the request task, eg. the url, or the method being used.context
(Object) Additional context data (usually contains the same data as the associated non-request metric event).stack
(String) An optional stack trace for the event call.children
(Array) An array of child request events that occurred as part of the overall request event. Child request events may include function trace entries, which will have a type
of null.duration
(Number) the time taken for the request to complete in ms.duration
(Number) the time taken for the overall request to complete in ms.The Node Application Metrics agent supports the following runtime environments where a Node.js runtime is available:
npm install appmetrics
, ensure the environment variable CC=gcc
is set.Find below some possible problem scenarios and corresponding diagnostic steps. Updates to troubleshooting information will be made available on the appmetrics wiki: Troubleshooting. If these resources do not help you resolve the issue, you can open an issue on the Node Application Metrics appmetrics issue tracker.
By default, a message similar to the following will be written to console output when Node Application Metrics starts:
[Fri Aug 21 09:36:58 2015] com.ibm.diagnostics.healthcenter.loader INFO: Node Application Metrics 1.0.1-201508210934 (Agent Core 3.0.5.201508210934)
This error indicates there was a problem while loading the native part of the module or one of its dependent libraries. On Windows, appmetrics.node
depends on a particular version of the C runtime library and if it cannot be found this error is the likely result.
Check:
appmetrics.node
file exist in the indicated location? If not, try reinstalling the module.1.0.0
on Windows: are msvcr100.dll
and msvcp100.dll
installed on your Windows system, and do they match the bitness (32-bit or 64-bit) of your Node.js runtime environment? If not, you may be able to install them with the Visual C++ Redistributable Packages for Visual Studio 2010 package from the Microsoft website.1.0.1
on Windows: does msvcr120.dll
and msvcp120.dll
exist in the module installation directory (see Installation) and does it match the bitness of your Node.js runtime environment? If not, try reinstalling the module.Note: On Windows, the global module installation directory might be shared between multiple Node.js runtime environments. This can cause problems with globally installed modules with native components, particularly if some of the Node.js runtime environments are 32-bit and others are 64-bit because the native components will only work with those with matching bitness.
This error indicates there was a problem while loading the native part of the module or one of its dependent libraries. On non-Windows platforms, libagentcore.so
depends on a particular (minimum) version of the C runtime library and if it cannot be found this error is the result.
Check:
libstdc++
installed. You may need to install or update a package in your package manager. If your OS does not supply a package at this version, you may have to install standalone software - consult the documentation or support forums for your OS.libstdc++
installed, ensure it is on the system library path, or use a method (such as setting LD_LIBRARY_PATH
environment variable on Linux, or LIBPATH environment variable on AIX) to add the library to the search path.Method profiling data is not collected by default, check Configuring Node Application Metrics for information on how to enable it.
If collection is enabled, an absence of method profiling data from a Node.js application could be caused by the type of tasks that are being run by your application -- it may be running long, synchronous tasks that prevent collection events from being scheduled on the event loop.
If a task uses the Node.js thread exclusively then shuts down the Node.js runtime environment, the Health Center agent may not get the opportunity to obtain any profiling data. An example of such an application is the Octane JavaScript benchmark suite, which loads the CPU continuously rather than dividing the load across multiple units of work.
The source code for Node Application Metrics is available in the appmetrics project. Information on working with the source code -- installing from source, developing, contributing -- is available on the appmetrics wiki.
This project is released under an Apache 2.0 open source license.
The npm package for this project uses a semver-parsable X.0.Z version number for releases, where X is incremented for breaking changes to the public API described in this document and Z is incremented for bug fixes and for non-breaking changes to the public API that provide new function.
Non-release versions of this project (for example on github.com/RuntimeTools/appmetrics) will use semver-parsable X.0.Z-dev.B version numbers, where X.0.Z is the last release with Z incremented and B is an integer. For further information on the development process go to the appmetrics wiki: Developing.
This module adopts the Module Long Term Support (LTS) policy, with the following End Of Life (EOL) dates:
Module Version | Release Date | Minimum EOL | EOL With | Status |
---|---|---|---|---|
V4.x.x | Jan 2018 | Dec 2019 | Maintenance | |
V5.x.x | May 2019 | Dec 2020 | Current |
5.1.1
5.1.1
- Node13 support, bump dependency versions and a trace probe fix.5.0.5
- zAppmetrics fixes, and bump agentcore for Alpine support.5.0.3
- Bug fix.5.0.2
- Bump level of omragentcore.5.0.1
- Bug fix for incorrect timiings on http request.5.0.0
- Add Node 12 support, remove Node 6 support.4.0.1
- Bug fix release including adding Node 10 support on Windows (Unix already working).4.0.0
- Remove node-hc and add support for preloading.3.1.3
- Packaging fix.3.1.2
- Bug fixes.3.1.1
- Node v6 on z/OS support.3.1.0
- HTTPS probe added. Remove support for Node v7.3.0.2
- Probe defect for Node 8 support.3.0.1
- Packaging bug fix to allow build from source if binary not present.3.0.0
- Remove express probe. Additional data available in http and request events. Code improvements.2.0.1
- Remove support for Node.js 0.10, 0.12, 5. Add heapdump api call.1.2.0
- Add file data collection capability and option configuration via api.1.1.2
- Update agent core to 3.0.10, support Node.js v7.1.1.1
- Fix node-gyp rebuild failure and don't force MQTT broker to on1.1.0
- Bug fixes, improved MongoDB data, updated dependencies, CPU watchdog feature1.0.13
- Express probe, strong-supervisor integration1.0.12
- Appmetrics now fully open sourced under Apache 2.0 license1.0.11
- Bug fixes1.0.10
- Bug fixes1.0.9
- Loopback and Riak support, bug fixes and update to agent core 3.0.9.1.0.8
- Oracle support, bug fixes and api tests runnable using 'npm test'.1.0.7
- StrongOracle support, support for installing with a proxy, expose MongoDB, MQLight and MySQL events to connectors.1.0.6
- OracleDB support and bug fixes.1.0.5
- Expose HTTP events to connectors (including MQTT).1.0.4
- Redis, Leveldown, Postgresql, Memcached, MQLight and MQTT support, higher precision timings, and improved performance.1.0.3
- Node.js v4 support.1.0.2
- HTTP, MySQL, MongoDB, request tracking and function tracing support.1.0.1
- Mac OS X support, io.js v2 support.1.0.0
- First release.
Author: RuntimeTools
Source Code: https://github.com/RuntimeTools/appmetrics
License: Apache-2.0 license
1660739520
Trong hướng dẫn ngắn gọn này, Chúng tôi sẽ chia sẻ Cách kết nối MongoDB với một ứng dụng Node.js trong Kubernetes với các bước theo từng bước.
Bài viết trước đã thiết lập quyền truy cập giữa MongoDB Atlas và cụm OpenShift của bạn. Nếu bạn đã thực hiện thành công các bước đó, bạn đã sẵn sàng triển khai cơ sở dữ liệu MongoDB được lưu trữ trên đám mây trong cụm như sau:
Hình 1: Chế độ xem Topo cho thấy rằng MongoDB Atlas hiện có thể truy cập được trong cụm của bạn.
Có một số cách để triển khai ứng dụng Node.js trong OpenShift: Thông qua oc
giao diện dòng lệnh OpenShift (CLI), odo
CLI, bảng điều khiển OpenShift, v.v. Bài viết này đề cập đến hai tùy chọn: Bảng điều khiển OpenShift và Nodeshift , một gói NPM.
Từ góc độ Nhà phát triển , chọn + Thêm → Nhập từ Git .
Trong trường url kho lưu trữ Git , hãy đặt URL kho lưu trữ thành https://github.com/nodeshift-blog-examples/kube-service-bindings-examples
. Đây là kho lưu trữ ví dụ về kube-service-bindings được duy trì bởi nhóm của chúng tôi; nó chứa ứng dụng Node.js mà bạn đang triển khai trong bài viết này.
Mở rộng Hiển thị các tùy chọn Git nâng cao . Trên trường Dir ngữ cảnh , hãy đặt giá trị thành src/mongodb
, là đường dẫn của thư mục con nơi đặt ứng dụng Node.js của bạn.
Trên Hình ảnh trình dựng , chọn Node.js và nhấp vào Tạo .
Mở một thiết bị đầu cuối và sao chép kho lưu trữ git:
git clone https://github.com/nodeshift-blog-examples/kube-service-bindings-examples.git
$ cd ./kube-service-bindings-examples/src/mongodb
Cài đặt Nodeshift trên toàn cầu:
$ npm install -g nodeshift
Để tìm thông tin đăng nhập được yêu cầu bởi lệnh tiếp theo mà bạn sẽ sử dụng, hãy truy cập bảng điều khiển OpenShift của bạn. Ở góc trên bên phải, nhấp vào tên người dùng của bạn. Một danh sách thả xuống sẽ xuất hiện. Nhấp vào Sao chép lệnh đăng nhập (Hình 2), lệnh này sẽ chuyển bạn đến một trang khác. Sau đó nhấp vào Mã thông báo hiển thị để hiển thị tên người dùng, mật khẩu và thông tin đăng nhập máy chủ để đăng nhập với Nodeshift.
Hình 2: Dưới tên của bạn trong bảng điều khiển, bạn có thể lấy thông tin đăng nhập.
Sử dụng các thông tin đăng nhập này, bây giờ bạn có thể đăng nhập vào cụm OpenShift của mình bằng Nodeshift:
$ nodeshift login --username=developer --password=password --server=https://api.server
Triển khai ứng dụng Node.js với Nodeshift thông qua lệnh sau, thay thế tên không gian tên bằng tên dự án cụ thể của bạn:
$ nodeshift --namespace.name=<selected-project>
Ứng dụng của bạn sẽ được triển khai và hiển thị trong dạng xem Topo, như trong Hình 3.
Hình 3: Ứng dụng Node.js xuất hiện trong dạng xem Topo.
Bước cuối cùng trong loạt bài này là thiết lập kết nối giữa ứng dụng Node.js của bạn và cơ sở dữ liệu MongoDB, mà chúng ta sẽ thực hiện trong phần này.
Tại thời điểm này, hai trường hợp sẽ hiển thị trong dạng xem Topo của bạn: ứng dụng Node.js và kết nối với cá thể MongoDB của bạn trong Atlas (Hình 4).
Hình 4: Dạng xem Topo cho thấy cả ứng dụng Node.js và cơ sở dữ liệu MongoDB bên ngoài.
Để thiết lập kết nối giữa các trường hợp này, bạn sẽ sử dụng Nhà điều hành ràng buộc dịch vụ để chia sẻ thông tin xác thực và kube-service-bindings để phân tích cú pháp các thông tin xác thực đó (dữ liệu ràng buộc).
Bạn có thể tạo Ràng buộc dịch vụ theo hai cách khác nhau:
Chúng tôi sẽ đi với tùy chọn đầu tiên, trong trường hợp của chúng tôi là nhanh hơn và dễ dàng hơn.
Di chuột qua ứng dụng Node.js trong dạng xem Topo. Một mũi tên sẽ xuất hiện. Kéo mũi tên từ ứng dụng Node.js vào vòng tròn xung quanh cá thể MongoDB. Chú giải công cụ sẽ hiển thị có nội dung Tạo liên kết dịch vụ . Thả nút chuột và một hộp bật lên sẽ cho phép bạn chỉ định tên của ràng buộc dịch vụ. Nhấp vào Tạo ràng buộc . Vùng chứa của ứng dụng Node.js sẽ khởi động lại ngay lập tức (Hình 5).
Kiểm tra môi trường của ứng dụng Node.js bằng cách nhấp vào vùng chứa ứng dụng Node.js trong dạng xem Topo. Trong thanh bên bên phải, nhấp vào Tài nguyên → Xem Nhật ký (Phần nhóm) và truy cập tab Môi trường . Biến SERVICE_BINDING_ROOT
môi trường nên được thiết lập, như thể hiện trong Hình 6.
Bước cuối cùng là đọc dữ liệu ràng buộc trong thư mục được chỉ định bởi SERVICE_BINDING_ROOT
biến và chuyển dữ liệu đến máy khách MongoDB để thiết lập kết nối với cơ sở dữ liệu MongoDB. Ứng dụng Node.js của bạn đã có kube-service-bindings như một phần phụ thuộc. Vì vậy, việc gọi getBinding()
hàm, như được hiển thị trong đoạn mã JavaScript sau, thực hiện tất cả các công việc khó khăn là phân tích cú pháp, làm sạch và chuyển đổi dữ liệu liên kết thành định dạng có thể sử dụng được cho ứng dụng khách MongoDB:
const { MongoClient } = require("mongodb");
const serviceBindings = require("kube-service-bindings");
const { url, connectionOptions } = serviceBindings.getBinding("MONGODB", "mongodb");
const mongoClient = new MongoClient(url, connectionOptions);
Đó là nó. Bằng cách truy cập URL của ứng dụng Node.js (nhấp vào biểu tượng hộp mũi tên trên nút), bạn có thể thực hiện các thao tác CRUD đơn giản thông qua giao diện người dùng trên cơ sở dữ liệu.
Trong năm qua, nhóm của chúng tôi đã tích cực phát triển các ràng buộc dịch vụ kube, giúp các nhà phát triển có ít hoặc không có kinh nghiệm trong việc quản lý các ứng dụng chứa trong container dễ dàng chia sẻ thông tin đăng nhập giữa các dịch vụ hỗ trợ một cách dễ dàng hơn.
Bổ sung cho công việc phát triển kube-service-bindings , nhóm của chúng tôi cung cấp các ví dụ cho hầu hết các khách hàng được hỗ trợ bởi kube-service-bindings, hướng dẫn sử dụng kube-service-bindings và mô tả về cách triển khai nhiều dịch vụ hỗ trợ thông qua Nodeshift trong môi trường Kubernetes và OpenShift.
Loạt bài viết này đã chỉ ra những ứng dụng khách nào được hỗ trợ và cách thức hoạt động của cả ràng buộc dịch vụ và ràng buộc dịch vụ kube. Chúng tôi đã hướng dẫn bạn toàn bộ chu trình triển khai dịch vụ sao lưu ứng dụng Node.js bằng cách sử dụng SBO và kube-service-bindings, chia sẻ và phân tích cú pháp thông tin xác thực cho kết nối giữa ứng dụng Node.js và cơ sở dữ liệu MongoDB. kube-service-bindings đọc, phân tích cú pháp và chuyển đổi dữ liệu ràng buộc do Nhà điều hành Service Binding dự kiến, trả về dữ liệu ở dạng được ứng dụng MongoDB trực tiếp sử dụng.
Để giúp bạn sử dụng kube-service-bindings trong các kiểu triển khai khác, chúng tôi đã cung cấp thêm các ví dụ về Node.js. Chúng tôi hy vọng bạn thấy bài viết này thú vị và bây giờ đã hiểu rõ hơn về kube-service-bindings và các ràng buộc dịch vụ nói chung.
#node #nodejs #mongodb #database #kubernetes
1660732278
Dans ce bref guide, nous partagerons comment connecter MongoDB à une application Node.js dans Kubernetes étape par étape.
L'article précédent a configuré l'accès entre MongoDB Atlas et votre cluster OpenShift. Si vous avez suivi ces étapes avec succès, vous êtes prêt à déployer une base de données MongoDB hébergée dans le cloud dans le cluster comme suit :
Figure 1 : La vue Topologie montre que MongoDB Atlas est désormais accessible dans votre cluster.
Il existe plusieurs façons de déployer une application Node.js dans OpenShift : via l' oc
interface de ligne de commande (CLI) OpenShift, la odo
CLI, la console OpenShift, etc. Cet article couvre deux options : la console OpenShift et Nodeshift , un package NPM.
Du point de vue du développeur, sélectionnez +Ajouter→Importer depuis Git .
Dans le champ URL du référentiel Git , définissez l'URL du référentiel sur https://github.com/nodeshift-blog-examples/kube-service-bindings-examples
. Il s'agit d'un référentiel d'exemples kube-service-bindings maintenu par notre équipe ; il contient l'application Node.js que vous déployez dans cet article.
Développez Afficher les options avancées de Git . Dans le champ Context dir , définissez la valeur sur src/mongodb
, qui est le chemin du sous-répertoire où se trouve votre application Node.js.
Sur Builder Image , sélectionnez Node.js et cliquez sur Create .
Ouvrez un terminal et clonez le dépôt git :
git clone https://github.com/nodeshift-blog-examples/kube-service-bindings-examples.git
$ cd ./kube-service-bindings-examples/src/mongodb
Installez Nodeshift globalement :
$ npm install -g nodeshift
Pour trouver les identifiants de connexion requis par la prochaine commande que vous utiliserez, visitez votre console OpenShift. Dans le coin supérieur droit, cliquez sur votre nom d'utilisateur. Une liste déroulante apparaîtra. Cliquez sur Copier la commande de connexion (Figure 2), qui vous transfère vers une autre page. Cliquez ensuite sur Afficher le jeton pour afficher le nom d'utilisateur, le mot de passe et les informations d'identification du serveur pour vous connecter à Nodeshift.
Figure 2 : Sous votre nom dans la console, vous pouvez obtenir des identifiants de connexion.
À l'aide de ces informations d'identification, vous pouvez désormais vous connecter à votre cluster OpenShift avec Nodeshift :
$ nodeshift login --username=developer --password=password --server=https://api.server
Déployez l'application Node.js avec Nodeshift via la commande suivante, en remplaçant le nom de l'espace de noms par le nom de votre projet :
$ nodeshift --namespace.name=<selected-project>
Votre application doit être déployée et visible dans la vue Topologie, comme illustré à la figure 3.
Figure 3 : L'application Node.js apparaît dans la vue Topologie.
La dernière étape de cette série consiste à établir une connexion entre votre application Node.js et la base de données MongoDB, ce que nous accomplirons dans cette section.
À ce stade, deux instances doivent apparaître dans votre vue Topologie : l'application Node.js et la connexion à votre instance MongoDB dans Atlas (Figure 4).
Figure 4 : La vue Topologie affiche à la fois l'application Node.js et la base de données MongoDB externe.
Pour établir une connexion entre ces instances, vous utiliserez l'opérateur de liaison de service pour partager les informations d'identification et kube-service-bindings pour analyser ces informations d'identification (données de liaison).
Vous pouvez créer une liaison de service de deux manières différentes :
Nous allons opter pour la première option, qui dans notre cas est plus rapide et plus facile.
Passez la souris sur l'application Node.js dans la vue Topologie. Une flèche devrait apparaître. Faites glisser la flèche de l'application Node.js vers le cercle autour de l'instance MongoDB. Une info-bulle devrait être visible indiquant Créer une liaison de service . Relâchez le bouton de la souris et une fenêtre contextuelle vous permettra de spécifier le nom de la liaison de service. Cliquez sur Créer une liaison . Le conteneur de l'application Node.js redémarrera immédiatement (Figure 5).
Vérifiez l'environnement de l'application Node.js en cliquant sur le conteneur d'application Node.js dans la vue Topologie. Dans la barre latérale droite, cliquez sur Ressources → Afficher les journaux (section Pods) et visitez l' onglet Environnement . La SERVICE_BINDING_ROOT
variable d'environnement doit être définie, comme illustré à la figure 6.
La dernière étape consiste à lire les données de liaison sous le répertoire indiqué par la SERVICE_BINDING_ROOT
variable et à transmettre les données au client MongoDB pour établir une connexion à la base de données MongoDB. Votre application Node.js a déjà kube-service-bindings comme dépendance. Ainsi, l'appel de la getBinding()
fonction, comme indiqué dans l'extrait de code JavaScript suivant, effectue tout le travail difficile d'analyse, de nettoyage et de transformation des données de liaison en un format consommable pour le client MongoDB :
const { MongoClient } = require("mongodb");
const serviceBindings = require("kube-service-bindings");
const { url, connectionOptions } = serviceBindings.getBinding("MONGODB", "mongodb");
const mongoClient = new MongoClient(url, connectionOptions);
C'est ça. En visitant l'URL de l'application Node.js (cliquez sur l'icône représentant une flèche sur le nœud), vous pouvez effectuer des opérations CRUD simples via l'interface utilisateur de la base de données.
Au cours de l'année écoulée, notre équipe a été active dans le développement de kube-service-bindings, ce qui permet aux développeurs peu ou pas expérimentés dans la gestion d'applications conteneurisées de partager en toute sécurité les informations d'identification entre les services de support.
En complément du travail sur le développement de kube-service-bindings , notre équipe fournit des exemples pour la plupart des clients pris en charge par kube-service-bindings, des instructions sur l'utilisation de kube-service-bindings et une description de la façon de déployer une variété de services de support via Nodeshift dans les environnements Kubernetes et OpenShift.
Cette série d'articles a montré quels clients sont pris en charge et comment fonctionnent à la fois une liaison de service et kube-service-bindings. Nous vous avons guidé tout au long du cycle de déploiement d'un service de sauvegarde d'application Node.js à l'aide des liaisons SBO et kube-service, en partageant et en analysant les informations d'identification pour une connexion entre une application Node.js et une base de données MongoDB. kube-service-bindings lit, analyse et transforme les données de liaison projetées par l'opérateur de liaison de service, renvoyant les données sous une forme directement consommable par le client MongoDB.
Pour vous aider à utiliser kube-service-bindings dans d'autres types de déploiements, nous avons fourni des exemples Node.js supplémentaires . Nous espérons que vous avez trouvé cet article intéressant et que vous avez maintenant une meilleure compréhension de kube-service-bindings et des liaisons de service en général.
#node #nodejs #mongodb #database #kubernetes
1660725480
Enquirer
Stylish CLI prompts that are user-friendly, intuitive and easy to create.
>_ Prompts should be more like conversations than inquisitions▌
(Example shows Enquirer's Survey Prompt)
The terminal in all examples is Hyper, theme is hyper-monokai-extended.
See more prompt examples
Created by jonschlinkert and doowb, Enquirer is fast, easy to use, and lightweight enough for small projects, while also being powerful and customizable enough for the most advanced use cases.
If you like Enquirer, please consider starring or tweeting about this project to show your support. Thanks!
>_ Ready to start making prompts your users will love? ▌
Get started with Enquirer, the most powerful and easy-to-use Node.js library for creating interactive CLI prompts.
Install with npm:
$ npm install enquirer --save
Install with yarn:
$ yarn add enquirer
(Requires Node.js 8.6 or higher. Please let us know if you need support for an earlier version by creating an issue.)
The easiest way to get started with enquirer is to pass a question object to the prompt
method.
const { prompt } = require('enquirer');
const response = await prompt({
type: 'input',
name: 'username',
message: 'What is your username?'
});
console.log(response); // { username: 'jonschlinkert' }
(Examples with await
need to be run inside an async
function)
Pass an array of "question" objects to run a series of prompts.
const response = await prompt([
{
type: 'input',
name: 'name',
message: 'What is your name?'
},
{
type: 'input',
name: 'username',
message: 'What is your username?'
}
]);
console.log(response); // { name: 'Edward Chan', username: 'edwardmchan' }
built-in prompt
const { Confirm } = require('enquirer');
const prompt = new Confirm({
name: 'question',
message: 'Did you like enquirer?'
});
prompt.run()
.then(answer => console.log('Answer:', answer));
prompt
const { prompt } = require('enquirer');
prompt({
type: 'confirm',
name: 'question',
message: 'Did you like enquirer?'
})
.then(answer => console.log('Answer:', answer));
Jump to: Getting Started · Prompts · Options · Key Bindings
Enquirer is a prompt runner
Add Enquirer to your JavaScript project with following line of code.
const Enquirer = require('enquirer');
The main export of this library is the Enquirer
class, which has methods and features designed to simplify running prompts.
const { prompt } = require('enquirer');
const question = [
{
type: 'input',
name: 'username',
message: 'What is your username?'
},
{
type: 'password',
name: 'password',
message: 'What is your password?'
}
];
let answers = await prompt(question);
console.log(answers);
Prompts control how values are rendered and returned
Each individual prompt is a class with special features and functionality for rendering the types of values you want to show users in the terminal, and subsequently returning the types of values you need to use in your application.
How can I customize prompts?
Below in this guide you will find information about creating custom prompts. For now, we'll focus on how to customize an existing prompt.
All of the individual prompt classes in this library are exposed as static properties on Enquirer. This allows them to be used directly without using enquirer.prompt()
.
Use this approach if you need to modify a prompt instance, or listen for events on the prompt.
Example
const { Input } = require('enquirer');
const prompt = new Input({
name: 'username',
message: 'What is your username?'
});
prompt.run()
.then(answer => console.log('Username:', answer))
.catch(console.error);
Create an instance of Enquirer
.
Params
options
{Object}: (optional) Options to use with all prompts.answers
{Object}: (optional) Answers object to initialize with.Example
const Enquirer = require('enquirer');
const enquirer = new Enquirer();
Register a custom prompt type.
Params
type
{String}fn
{Function|Prompt}: Prompt
class, or a function that returns a Prompt
class.returns
{Object}: Returns the Enquirer instanceExample
const Enquirer = require('enquirer');
const enquirer = new Enquirer();
enquirer.register('customType', require('./custom-prompt'));
Prompt function that takes a "question" object or array of question objects, and returns an object with responses from the user.
Params
questions
{Array|Object}: Options objects for one or more prompts to run.returns
{Promise}: Promise that returns an "answers" object with the user's responses.Example
const Enquirer = require('enquirer');
const enquirer = new Enquirer();
const response = await enquirer.prompt({
type: 'input',
name: 'username',
message: 'What is your username?'
});
console.log(response);
Use an enquirer plugin.
Params
plugin
{Function}: Plugin function that takes an instance of Enquirer.returns
{Object}: Returns the Enquirer instance.Example
const Enquirer = require('enquirer');
const enquirer = new Enquirer();
const plugin = enquirer => {
// do stuff to enquire instance
};
enquirer.use(plugin);
Prompt function that takes a "question" object or array of question objects, and returns an object with responses from the user.
Params
questions
{Array|Object}: Options objects for one or more prompts to run.returns
{Promise}: Promise that returns an "answers" object with the user's responses.Example
const { prompt } = require('enquirer');
const response = await prompt({
type: 'input',
name: 'username',
message: 'What is your username?'
});
console.log(response);
This section is about Enquirer's prompts: what they look like, how they work, how to run them, available options, and how to customize the prompts or create your own prompt concept.
Getting started with Enquirer's prompts
Prompt
class used by other promptsPrompt
class used by other promptsThe base Prompt
class is used to create all other prompts.
const { Prompt } = require('enquirer');
class MyCustomPrompt extends Prompt {}
See the documentation for creating custom prompts to learn more about how this works.
Each prompt takes an options object (aka "question" object), that implements the following interface:
{
// required
type: string | function,
name: string | function,
message: string | function | async function,
// optional
skip: boolean | function | async function,
initial: string | function | async function,
format: function | async function,
result: function | async function,
validate: function | async function,
}
Each property of the options object is described below:
Property | Required? | Type | Description |
---|---|---|---|
type | yes | string|function | Enquirer uses this value to determine the type of prompt to run, but it's optional when prompts are run directly. |
name | yes | string|function | Used as the key for the answer on the returned values (answers) object. |
message | yes | string|function | The message to display when the prompt is rendered in the terminal. |
skip | no | boolean|function | If true it will not ask that prompt. |
initial | no | string|function | The default value to return if the user does not supply a value. |
format | no | function | Function to format user input in the terminal. |
result | no | function | Function to format the final submitted value before it's returned. |
validate | no | function | Function to validate the submitted value before it's returned. This function may return a boolean or a string. If a string is returned it will be used as the validation error message. |
Example usage
const { prompt } = require('enquirer');
const question = {
type: 'input',
name: 'username',
message: 'What is your username?'
};
prompt(question)
.then(answer => console.log('Answer:', answer))
.catch(console.error);
Prompt that auto-completes as the user types, and returns the selected value as a string.
Example Usage
const { AutoComplete } = require('enquirer');
const prompt = new AutoComplete({
name: 'flavor',
message: 'Pick your favorite flavor',
limit: 10,
initial: 2,
choices: [
'Almond',
'Apple',
'Banana',
'Blackberry',
'Blueberry',
'Cherry',
'Chocolate',
'Cinnamon',
'Coconut',
'Cranberry',
'Grape',
'Nougat',
'Orange',
'Pear',
'Pineapple',
'Raspberry',
'Strawberry',
'Vanilla',
'Watermelon',
'Wintergreen'
]
});
prompt.run()
.then(answer => console.log('Answer:', answer))
.catch(console.error);
AutoComplete Options
Option | Type | Default | Description |
---|---|---|---|
highlight | function | dim version of primary style | The color to use when "highlighting" characters in the list that match user input. |
multiple | boolean | false | Allow multiple choices to be selected. |
suggest | function | Greedy match, returns true if choice message contains input string. | Function that filters choices. Takes user input and a choices array, and returns a list of matching choices. |
initial | number | 0 | Preselected item in the list of choices. |
footer | function | None | Function that displays footer text |
Related prompts
↑ back to: Getting Started · Prompts
Prompt that asks for username and password to authenticate the user. The default implementation of authenticate
function in BasicAuth
prompt is to compare the username and password with the values supplied while running the prompt. The implementer is expected to override the authenticate
function with a custom logic such as making an API request to a server to authenticate the username and password entered and expect a token back.
Example Usage
const { BasicAuth } = require('enquirer');
const prompt = new BasicAuth({
name: 'password',
message: 'Please enter your password',
username: 'rajat-sr',
password: '123',
showPassword: true
});
prompt
.run()
.then(answer => console.log('Answer:', answer))
.catch(console.error);
↑ back to: Getting Started · Prompts
Prompt that returns true
or false
.
Example Usage
const { Confirm } = require('enquirer');
const prompt = new Confirm({
name: 'question',
message: 'Want to answer?'
});
prompt.run()
.then(answer => console.log('Answer:', answer))
.catch(console.error);
Related prompts
↑ back to: Getting Started · Prompts
Prompt that allows the user to enter and submit multiple values on a single terminal screen.
Example Usage
const { Form } = require('enquirer');
const prompt = new Form({
name: 'user',
message: 'Please provide the following information:',
choices: [
{ name: 'firstname', message: 'First Name', initial: 'Jon' },
{ name: 'lastname', message: 'Last Name', initial: 'Schlinkert' },
{ name: 'username', message: 'GitHub username', initial: 'jonschlinkert' }
]
});
prompt.run()
.then(value => console.log('Answer:', value))
.catch(console.error);
Related prompts
↑ back to: Getting Started · Prompts
Prompt that takes user input and returns a string.
Example Usage
const { Input } = require('enquirer');
const prompt = new Input({
message: 'What is your username?',
initial: 'jonschlinkert'
});
prompt.run()
.then(answer => console.log('Answer:', answer))
.catch(console.log);
You can use data-store to store input history that the user can cycle through (see source).
Related prompts
↑ back to: Getting Started · Prompts
Prompt that takes user input, hides it from the terminal, and returns a string.
Example Usage
const { Invisible } = require('enquirer');
const prompt = new Invisible({
name: 'secret',
message: 'What is your secret?'
});
prompt.run()
.then(answer => console.log('Answer:', { secret: answer }))
.catch(console.error);
Related prompts
↑ back to: Getting Started · Prompts
Prompt that returns a list of values, created by splitting the user input. The default split character is ,
with optional trailing whitespace.
Example Usage
const { List } = require('enquirer');
const prompt = new List({
name: 'keywords',
message: 'Type comma-separated keywords'
});
prompt.run()
.then(answer => console.log('Answer:', answer))
.catch(console.error);
Related prompts
↑ back to: Getting Started · Prompts
Prompt that allows the user to select multiple items from a list of options.
Example Usage
const { MultiSelect } = require('enquirer');
const prompt = new MultiSelect({
name: 'value',
message: 'Pick your favorite colors',
limit: 7,
choices: [
{ name: 'aqua', value: '#00ffff' },
{ name: 'black', value: '#000000' },
{ name: 'blue', value: '#0000ff' },
{ name: 'fuchsia', value: '#ff00ff' },
{ name: 'gray', value: '#808080' },
{ name: 'green', value: '#008000' },
{ name: 'lime', value: '#00ff00' },
{ name: 'maroon', value: '#800000' },
{ name: 'navy', value: '#000080' },
{ name: 'olive', value: '#808000' },
{ name: 'purple', value: '#800080' },
{ name: 'red', value: '#ff0000' },
{ name: 'silver', value: '#c0c0c0' },
{ name: 'teal', value: '#008080' },
{ name: 'white', value: '#ffffff' },
{ name: 'yellow', value: '#ffff00' }
]
});
prompt.run()
.then(answer => console.log('Answer:', answer))
.catch(console.error);
// Answer: ['aqua', 'blue', 'fuchsia']
Example key-value pairs
Optionally, pass a result
function and use the .map
method to return an object of key-value pairs of the selected names and values: example
const { MultiSelect } = require('enquirer');
const prompt = new MultiSelect({
name: 'value',
message: 'Pick your favorite colors',
limit: 7,
choices: [
{ name: 'aqua', value: '#00ffff' },
{ name: 'black', value: '#000000' },
{ name: 'blue', value: '#0000ff' },
{ name: 'fuchsia', value: '#ff00ff' },
{ name: 'gray', value: '#808080' },
{ name: 'green', value: '#008000' },
{ name: 'lime', value: '#00ff00' },
{ name: 'maroon', value: '#800000' },
{ name: 'navy', value: '#000080' },
{ name: 'olive', value: '#808000' },
{ name: 'purple', value: '#800080' },
{ name: 'red', value: '#ff0000' },
{ name: 'silver', value: '#c0c0c0' },
{ name: 'teal', value: '#008080' },
{ name: 'white', value: '#ffffff' },
{ name: 'yellow', value: '#ffff00' }
],
result(names) {
return this.map(names);
}
});
prompt.run()
.then(answer => console.log('Answer:', answer))
.catch(console.error);
// Answer: { aqua: '#00ffff', blue: '#0000ff', fuchsia: '#ff00ff' }
Related prompts
↑ back to: Getting Started · Prompts
Prompt that takes a number as input.
Example Usage
const { NumberPrompt } = require('enquirer');
const prompt = new NumberPrompt({
name: 'number',
message: 'Please enter a number'
});
prompt.run()
.then(answer => console.log('Answer:', answer))
.catch(console.error);
Related prompts
↑ back to: Getting Started · Prompts
Prompt that takes user input and masks it in the terminal. Also see the invisible prompt
Example Usage
const { Password } = require('enquirer');
const prompt = new Password({
name: 'password',
message: 'What is your password?'
});
prompt.run()
.then(answer => console.log('Answer:', answer))
.catch(console.error);
Related prompts
↑ back to: Getting Started · Prompts
Prompt that allows the user to play multiple-choice quiz questions.
Example Usage
const { Quiz } = require('enquirer');
const prompt = new Quiz({
name: 'countries',
message: 'How many countries are there in the world?',
choices: ['165', '175', '185', '195', '205'],
correctChoice: 3
});
prompt
.run()
.then(answer => {
if (answer.correct) {
console.log('Correct!');
} else {
console.log(`Wrong! Correct answer is ${answer.correctAnswer}`);
}
})
.catch(console.error);
Quiz Options
Option | Type | Required | Description |
---|---|---|---|
choices | array | Yes | The list of possible answers to the quiz question. |
correctChoice | number | Yes | Index of the correct choice from the choices array. |
↑ back to: Getting Started · Prompts
Prompt that allows the user to provide feedback for a list of questions.
Example Usage
const { Survey } = require('enquirer');
const prompt = new Survey({
name: 'experience',
message: 'Please rate your experience',
scale: [
{ name: '1', message: 'Strongly Disagree' },
{ name: '2', message: 'Disagree' },
{ name: '3', message: 'Neutral' },
{ name: '4', message: 'Agree' },
{ name: '5', message: 'Strongly Agree' }
],
margin: [0, 0, 2, 1],
choices: [
{
name: 'interface',
message: 'The website has a friendly interface.'
},
{
name: 'navigation',
message: 'The website is easy to navigate.'
},
{
name: 'images',
message: 'The website usually has good images.'
},
{
name: 'upload',
message: 'The website makes it easy to upload images.'
},
{
name: 'colors',
message: 'The website has a pleasing color palette.'
}
]
});
prompt.run()
.then(value => console.log('ANSWERS:', value))
.catch(console.error);
Related prompts
A more compact version of the Survey prompt, the Scale prompt allows the user to quickly provide feedback using a Likert Scale.
Example Usage
const { Scale } = require('enquirer');
const prompt = new Scale({
name: 'experience',
message: 'Please rate your experience',
scale: [
{ name: '1', message: 'Strongly Disagree' },
{ name: '2', message: 'Disagree' },
{ name: '3', message: 'Neutral' },
{ name: '4', message: 'Agree' },
{ name: '5', message: 'Strongly Agree' }
],
margin: [0, 0, 2, 1],
choices: [
{
name: 'interface',
message: 'The website has a friendly interface.',
initial: 2
},
{
name: 'navigation',
message: 'The website is easy to navigate.',
initial: 2
},
{
name: 'images',
message: 'The website usually has good images.',
initial: 2
},
{
name: 'upload',
message: 'The website makes it easy to upload images.',
initial: 2
},
{
name: 'colors',
message: 'The website has a pleasing color palette.',
initial: 2
}
]
});
prompt.run()
.then(value => console.log('ANSWERS:', value))
.catch(console.error);
Related prompts
↑ back to: Getting Started · Prompts
Prompt that allows the user to select from a list of options.
Example Usage
const { Select } = require('enquirer');
const prompt = new Select({
name: 'color',
message: 'Pick a flavor',
choices: ['apple', 'grape', 'watermelon', 'cherry', 'orange']
});
prompt.run()
.then(answer => console.log('Answer:', answer))
.catch(console.error);
Related prompts
↑ back to: Getting Started · Prompts
Prompt that allows the user to sort items in a list.
Example
In this example, custom styling is applied to the returned values to make it easier to see what's happening.
Example Usage
const colors = require('ansi-colors');
const { Sort } = require('enquirer');
const prompt = new Sort({
name: 'colors',
message: 'Sort the colors in order of preference',
hint: 'Top is best, bottom is worst',
numbered: true,
choices: ['red', 'white', 'green', 'cyan', 'yellow'].map(n => ({
name: n,
message: colors[n](n)
}))
});
prompt.run()
.then(function(answer = []) {
console.log(answer);
console.log('Your preferred order of colors is:');
console.log(answer.map(key => colors[key](key)).join('\n'));
})
.catch(console.error);
Related prompts
↑ back to: Getting Started · Prompts
Prompt that allows the user to replace placeholders in a snippet of code or text.
Example Usage
const semver = require('semver');
const { Snippet } = require('enquirer');
const prompt = new Snippet({
name: 'username',
message: 'Fill out the fields in package.json',
required: true,
fields: [
{
name: 'author_name',
message: 'Author Name'
},
{
name: 'version',
validate(value, state, item, index) {
if (item && item.name === 'version' && !semver.valid(value)) {
return prompt.styles.danger('version should be a valid semver value');
}
return true;
}
}
],
template: `{
"name": "\${name}",
"description": "\${description}",
"version": "\${version}",
"homepage": "https://github.com/\${username}/\${name}",
"author": "\${author_name} (https://github.com/\${username})",
"repository": "\${username}/\${name}",
"license": "\${license:ISC}"
}
`
});
prompt.run()
.then(answer => console.log('Answer:', answer.result))
.catch(console.error);
Related prompts
↑ back to: Getting Started · Prompts
Prompt that allows the user to toggle between two values then returns true
or false
.
Example Usage
const { Toggle } = require('enquirer');
const prompt = new Toggle({
message: 'Want to answer?',
enabled: 'Yep',
disabled: 'Nope'
});
prompt.run()
.then(answer => console.log('Answer:', answer))
.catch(console.error);
Related prompts
↑ back to: Getting Started · Prompts
There are 5 (soon to be 6!) type classes:
Each type is a low-level class that may be used as a starting point for creating higher level prompts. Continue reading to learn how.
The ArrayPrompt
class is used for creating prompts that display a list of choices in the terminal. For example, Enquirer uses this class as the basis for the Select and Survey prompts.
In addition to the options available to all prompts, Array prompts also support the following options.
Option | Required? | Type | Description |
---|---|---|---|
autofocus | no | string|number | The index or name of the choice that should have focus when the prompt loads. Only one choice may have focus at a time. |
stdin | no | stream | The input stream to use for emitting keypress events. Defaults to process.stdin . |
stdout | no | stream | The output stream to use for writing the prompt to the terminal. Defaults to process.stdout . |
Array prompts have the following instance properties and getters.
Property name | Type | Description |
---|---|---|
choices | array | Array of choices that have been normalized from choices passed on the prompt options. |
cursor | number | Position of the cursor relative to the user input (string). |
enabled | array | Returns an array of enabled choices. |
focused | array | Returns the currently selected choice in the visible list of choices. This is similar to the concept of focus in HTML and CSS. Focused choices are always visible (on-screen). When a list of choices is longer than the list of visible choices, and an off-screen choice is focused, the list will scroll to the focused choice and re-render. |
focused | Gets the currently selected choice. Equivalent to prompt.choices[prompt.index] . | |
index | number | Position of the pointer in the visible list (array) of choices. |
limit | number | The number of choices to display on-screen. |
selected | array | Either a list of enabled choices (when options.multiple is true) or the currently focused choice. |
visible | string |
Method | Description |
---|---|
pointer() | Returns the visual symbol to use to identify the choice that currently has focus. The ❯ symbol is often used for this. The pointer is not always visible, as with the autocomplete prompt. |
indicator() | Returns the visual symbol that indicates whether or not a choice is checked/enabled. |
focus() | Sets focus on a choice, if it can be focused. |
Array prompts support the choices
option, which is the array of choices users will be able to select from when rendered in the terminal.
Type: string|object
Example
const { prompt } = require('enquirer');
const questions = [{
type: 'select',
name: 'color',
message: 'Favorite color?',
initial: 1,
choices: [
{ name: 'red', message: 'Red', value: '#ff0000' }, //<= choice object
{ name: 'green', message: 'Green', value: '#00ff00' }, //<= choice object
{ name: 'blue', message: 'Blue', value: '#0000ff' } //<= choice object
]
}];
let answers = await prompt(questions);
console.log('Answer:', answers.color);
Whether defined as a string or object, choices are normalized to the following interface:
{
name: string;
message: string | undefined;
value: string | undefined;
hint: string | undefined;
disabled: boolean | string | undefined;
}
Example
const question = {
name: 'fruit',
message: 'Favorite fruit?',
choices: ['Apple', 'Orange', 'Raspberry']
};
Normalizes to the following when the prompt is run:
const question = {
name: 'fruit',
message: 'Favorite fruit?',
choices: [
{ name: 'Apple', message: 'Apple', value: 'Apple' },
{ name: 'Orange', message: 'Orange', value: 'Orange' },
{ name: 'Raspberry', message: 'Raspberry', value: 'Raspberry' }
]
};
The following properties are supported on choice
objects.
Option | Type | Description |
---|---|---|
name | string | The unique key to identify a choice |
message | string | The message to display in the terminal. name is used when this is undefined. |
value | string | Value to associate with the choice. Useful for creating key-value pairs from user choices. name is used when this is undefined. |
choices | array | Array of "child" choices. |
hint | string | Help message to display next to a choice. |
role | string | Determines how the choice will be displayed. Currently the only role supported is separator . Additional roles may be added in the future (like heading , etc). Please create a [feature request] |
enabled | boolean | Enabled a choice by default. This is only supported when options.multiple is true or on prompts that support multiple choices, like MultiSelect. |
disabled | boolean|string | Disable a choice so that it cannot be selected. This value may either be true , false , or a message to display. |
indicator | string|function | Custom indicator to render for a choice (like a check or radio button). |
The AuthPrompt
is used to create prompts to log in user using any authentication method. For example, Enquirer uses this class as the basis for the BasicAuth Prompt. You can also find prompt examples in examples/auth/
folder that utilizes AuthPrompt
to create OAuth based authentication prompt or a prompt that authenticates using time-based OTP, among others.
AuthPrompt
has a factory function that creates an instance of AuthPrompt
class and it expects an authenticate
function, as an argument, which overrides the authenticate
function of the AuthPrompt
class.
Method | Description |
---|---|
authenticate() | Contain all the authentication logic. This function should be overridden to implement custom authentication logic. The default authenticate function throws an error if no other function is provided. |
Auth prompt supports the choices
option, which is the similar to the choices used in Form Prompt.
Example
const { AuthPrompt } = require('enquirer');
function authenticate(value, state) {
if (value.username === this.options.username && value.password === this.options.password) {
return true;
}
return false;
}
const CustomAuthPrompt = AuthPrompt.create(authenticate);
const prompt = new CustomAuthPrompt({
name: 'password',
message: 'Please enter your password',
username: 'rajat-sr',
password: '1234567',
choices: [
{ name: 'username', message: 'username' },
{ name: 'password', message: 'password' }
]
});
prompt
.run()
.then(answer => console.log('Authenticated?', answer))
.catch(console.error);
The BooleanPrompt
class is used for creating prompts that display and return a boolean value.
const { BooleanPrompt } = require('enquirer');
const prompt = new BooleanPrompt({
header: '========================',
message: 'Do you love enquirer?',
footer: '========================',
});
prompt.run()
.then(answer => console.log('Selected:', answer))
.catch(console.error);
Returns: boolean
The NumberPrompt
class is used for creating prompts that display and return a numerical value.
const { NumberPrompt } = require('enquirer');
const prompt = new NumberPrompt({
header: '************************',
message: 'Input the Numbers:',
footer: '************************',
});
prompt.run()
.then(answer => console.log('Numbers are:', answer))
.catch(console.error);
Returns: string|number
(number, or number formatted as a string)
The StringPrompt
class is used for creating prompts that display and return a string value.
const { StringPrompt } = require('enquirer');
const prompt = new StringPrompt({
header: '************************',
message: 'Input the String:',
footer: '************************'
});
prompt.run()
.then(answer => console.log('String is:', answer))
.catch(console.error);
Returns: string
With Enquirer 2.0, custom prompts are easier than ever to create and use.
How do I create a custom prompt?
Custom prompts are created by extending either:
const { Prompt } = require('enquirer');
class HaiKarate extends Prompt {
constructor(options = {}) {
super(options);
this.value = options.initial || 0;
this.cursorHide();
}
up() {
this.value++;
this.render();
}
down() {
this.value--;
this.render();
}
render() {
this.clear(); // clear previously rendered prompt from the terminal
this.write(`${this.state.message}: ${this.value}`);
}
}
// Use the prompt by creating an instance of your custom prompt class.
const prompt = new HaiKarate({
message: 'How many sprays do you want?',
initial: 10
});
prompt.run()
.then(answer => console.log('Sprays:', answer))
.catch(console.error);
If you want to be able to specify your prompt by type
so that it may be used alongside other prompts, you will need to first create an instance of Enquirer
.
const Enquirer = require('enquirer');
const enquirer = new Enquirer();
Then use the .register()
method to add your custom prompt.
enquirer.register('haikarate', HaiKarate);
Now you can do the following when defining "questions".
let spritzer = require('cologne-drone');
let answers = await enquirer.prompt([
{
type: 'haikarate',
name: 'cologne',
message: 'How many sprays do you need?',
initial: 10,
async onSubmit(name, value) {
await spritzer.activate(value); //<= activate drone
return value;
}
}
]);
These key combinations may be used with all prompts.
command | description |
---|---|
ctrl + c | Cancel the prompt. |
ctrl + g | Reset the prompt to its initial state. |
These combinations may be used on prompts that support user input (eg. input prompt, password prompt, and invisible prompt).
command | description |
---|---|
left | Move the cursor back one character. |
right | Move the cursor forward one character. |
ctrl + a | Move cursor to the start of the line |
ctrl + e | Move cursor to the end of the line |
ctrl + b | Move cursor back one character |
ctrl + f | Move cursor forward one character |
ctrl + x | Toggle between first and cursor position |
These key combinations may be used on prompts that support user input (eg. input prompt, password prompt, and invisible prompt).
command | description |
---|---|
ctrl + a | Move cursor to the start of the line |
ctrl + e | Move cursor to the end of the line |
ctrl + b | Move cursor back one character |
ctrl + f | Move cursor forward one character |
ctrl + x | Toggle between first and cursor position |
command (Mac) | command (Windows) | description |
---|---|---|
delete | backspace | Delete one character to the left. |
fn + delete | delete | Delete one character to the right. |
option + up | alt + up | Scroll to the previous item in history (Input prompt only, when history is enabled). |
option + down | alt + down | Scroll to the next item in history (Input prompt only, when history is enabled). |
These key combinations may be used on prompts that support multiple choices, such as the multiselect prompt, or the select prompt when the multiple
options is true.
command | description |
---|---|
space | Toggle the currently selected choice when options.multiple is true. |
number | Move the pointer to the choice at the given index. Also toggles the selected choice when options.multiple is true. |
a | Toggle all choices to be enabled or disabled. |
i | Invert the current selection of choices. |
g | Toggle the current choice group. |
command | description |
---|---|
fn + up | Decrease the number of visible choices by one. |
fn + down | Increase the number of visible choices by one. |
command | description |
---|---|
number | Move the pointer to the choice at the given index. Also toggles the selected choice when options.multiple is true. |
up | Move the pointer up. |
down | Move the pointer down. |
ctrl + a | Move the pointer to the first visible choice. |
ctrl + e | Move the pointer to the last visible choice. |
shift + up | Scroll up one choice without changing pointer position (locks the pointer while scrolling). |
shift + down | Scroll down one choice without changing pointer position (locks the pointer while scrolling). |
command (Mac) | command (Windows) | description |
---|---|---|
fn + left | home | Move the pointer to the first choice in the choices array. |
fn + right | end | Move the pointer to the last choice in the choices array. |
Please see CHANGELOG.md.
MacBook Pro, Intel Core i7, 2.5 GHz, 16 GB.
Time it takes for the module to load the first time (average of 3 runs):
enquirer: 4.013ms
inquirer: 286.717ms
Contributing
Pull requests and stars are always welcome. For bugs and feature requests, please create an issue.
We're currently working on documentation for the following items. Please star and watch the repository for updates!
Running Tests
Running and reviewing unit tests is a great way to get familiarized with a library and its API. You can install dependencies and run tests with the following command:
$ npm install && npm test
$ yarn && yarn test
Building docs
(This project's readme.md is generated by verb, please don't edit the readme directly. Any changes to the readme must be made in the .verb.md readme template.)
To generate the readme, run the following command:
$ npm install -g verbose/verb#dev verb-generate-readme && verb
Author: Enquirer
Source Code: https://github.com/enquirer/enquirer
License: MIT license
1660725060
In this brief guide, We will share How to Connect MongoDB To A Node.js Application in Kubernetes With Steps by Step.
The previous article set up access between MongoDB Atlas and your OpenShift cluster. If you went through those steps successfully, you are ready to deploy a cloud-hosted MongoDB database in the cluster as follows:
See more at: https://developers.redhat.com/articles/2022/08/16/connect-mongodb-nodejs-application-kube-service-bindings#
#node #nodejs #mongodb #database #kubernetes
1660721520
Fast and modern web development framework for Node.js.
Melonly is a fast and modern web development framework for Node.js. It makes it easy to create secure and fast web applications with awesome developer experience.
To run Melonly, your environment has to met few requirements:
First, you only have to install @melonly/cli
package before creating your first project:
$ npm install -g @melonly/cli
You can check the Melonly CLI version when it has been properly installed and you’ll be able to run melon commands.
$ melon -v
To create new Melonly project you can use the CLI. Just run the new
command in your directory:
$ melon new <project-name>
Melonly comes with frontend frameworks integration out-of-the-box. You can create your project with predefined React or Vue template.
$ melon new <project-name> --template=vue
Once your project has been created you can start it on the local server using npm start
:
$ cd <project-name>
$ npm start
Your application will be available on localhost:3000
by default. You can change the port in .env
configuration file.
If you don’t want to open the browser automatically, use the npm run start:dev
command.
If your project has been created using Vue or React template, you have to run npm run dev
command inside project’s resources
directory:
$ cd your-app\resources && npm run dev
# Then run in separate terminal instance:
$ cd your-app && npm start
We appreciate every willingness to help developing Melonly. This project is open-source. That means everyone can use and make it.
We encourage you to open issues and pull requests on this GitHub repository. It helps us a lot with developing the framework.
If you discovered any bug or security issue please open new issue / pull request in the repository or email me: dom.rajkowski@gmail.com.
Author: Doc077
Source code: https://github.com/Doc077/melonly-core
#react #typescript #javascript #nodejs
1660717800
在這個簡短的指南中,我們將逐步分享如何將 MongoDB 連接到 Kubernetes 中的 Node.js 應用程序。
上一篇文章設置了MongoDB Atlas和您的 OpenShift 集群之間的訪問。如果您成功完成了這些步驟,您就可以在集群中部署雲託管的 MongoDB 數據庫,如下所示:
圖 1:拓撲視圖顯示 MongoDB Atlas 現在可以在您的集群中訪問。
在 OpenShift 中部署 Node.js 應用程序有多種方法:通過oc
OpenShift 命令行界面 (CLI)、odo
CLI、OpenShift 控制台等。本文介紹了兩個選項:OpenShift 控制台和Nodeshift,一個 NPM 包。
從開發人員的角度來看,選擇+Add→Import from Git。
在Git Repo url字段中,將存儲庫 URL 設置為https://github.com/nodeshift-blog-examples/kube-service-bindings-examples
. 這是我們團隊維護的kube-service-bindings 示例存儲庫;它包含您在本文中部署的 Node.js 應用程序。
展開顯示高級 Git 選項。在Context dir字段中,將值設置為src/mongodb
,這是您的 Node.js 應用程序所在的子目錄的路徑。
在Builder Image上,選擇Node.js並單擊Create。
打開終端並克隆 git 存儲庫:
git clone https://github.com/nodeshift-blog-examples/kube-service-bindings-examples.git
$ cd ./kube-service-bindings-examples/src/mongodb
全局安裝 Nodeshift:
$ npm install -g nodeshift
要查找您將使用的下一個命令所需的登錄憑據,請訪問您的 OpenShift 控制台。在右上角,單擊您的用戶名。將出現一個下拉菜單。單擊複製登錄命令(圖 2),這會將您轉到另一個頁面。然後單擊顯示令牌以顯示用戶名、密碼和服務器憑據以使用 Nodeshift 登錄。
圖 2:在控制台中您的姓名下,您可以獲得登錄憑據。
使用這些憑據,您現在可以使用 Nodeshift 登錄到您的 OpenShift 集群:
$ nodeshift login --username=developer --password=password --server=https://api.server
通過以下命令使用 Nodeshift 部署 Node.js 應用程序,將命名空間名稱替換為您的特定項目名稱:
$ nodeshift --namespace.name=<selected-project>
您的應用程序應該已部署並在 Topology 視圖中可見,如圖 3 所示。
圖 3:Node.js 應用程序出現在 Topology 視圖中。
本系列的最後一步是在 Node.js 應用程序和 MongoDB 數據庫之間建立連接,我們將在本節中完成。
此時,拓撲視圖中應顯示兩個實例:Node.js 應用程序和與 Atlas 中的 MongoDB 實例的連接(圖 4)。
圖 4:拓撲視圖顯示 Node.js 應用程序和外部 MongoDB 數據庫。
要在這些實例之間建立連接,您將使用 Service Binding Operator 來共享憑證,並使用 kube-service-bindings 來解析這些憑證(綁定數據)。
您可以通過兩種不同的方式創建服務綁定:
我們將使用第一個選項,在我們的例子中它更快更容易。
將鼠標懸停在 Topology 視圖中的 Node.js 應用程序上。應該會出現一個箭頭。將箭頭從 Node.js 應用程序拖到 MongoDB 實例周圍的圓圈中。應該可以看到一個工具提示,上面寫著Create service binding。釋放鼠標按鈕,一個彈出框將讓您指定服務綁定的名稱。單擊創建綁定。Node.js 應用程序的容器將立即重新啟動(圖 5)。
通過單擊拓撲視圖中的 Node.js 應用程序容器檢查 Node.js 應用程序的環境。在右側邊欄中,單擊資源→查看日誌(Pods 部分)並訪問環境選項卡。應設置環境變量,SERVICE_BINDING_ROOT
如圖 6 所示。
最後一步是讀取SERVICE_BINDING_ROOT
變量所指示的目錄下的綁定數據,並將數據傳遞給MongoDB客戶端,建立與MongoDB數據庫的連接。您的 Node.js 應用程序已經將 kube-service-bindings 作為依賴項。因此,調用該getBinding()
函數,如以下 JavaScript 代碼片段所示,完成了解析、清理和將綁定數據轉換為 MongoDB 客戶端可使用格式的所有艱苦工作:
const { MongoClient } = require("mongodb");
const serviceBindings = require("kube-service-bindings");
const { url, connectionOptions } = serviceBindings.getBinding("MONGODB", "mongodb");
const mongoClient = new MongoClient(url, connectionOptions);
而已。通過訪問 Node.js 應用程序的 URL(單擊節點上的箭頭框圖標),您可以通過 UI 對數據庫執行簡單的 CRUD 操作。
在過去的一年裡,我們的團隊一直在積極開發 kube-service-bindings,讓在管理容器化應用程序方面經驗很少或沒有經驗的開發人員更容易在支持服務之間安全地共享憑證。
作為對kube-service-bindings 開發工作的補充,我們的團隊提供了 kube-service-bindings 支持的大多數客戶端的示例,使用 kube-service-bindings 的說明,以及如何通過以下方式部署各種後端服務的描述Kubernetes 和 OpenShift 環境中的 Nodeshift。
本系列文章展示了支持哪些客戶端以及服務綁定和 kube-service-bindings 是如何工作的。我們指導您完成了使用 SBO 和 kube-service-bindings 部署 Node.js 應用程序支持服務、共享和解析 Node.js 應用程序和 MongoDB 數據庫之間連接的憑據的整個週期。kube-service-bindings 讀取、解析和轉換 Service Binding Operator 投射的綁定數據,以 MongoDB 客戶端可直接使用的形式返回數據。
為了幫助您在其他類型的部署中使用 kube-service-bindings,我們提供了額外的Node.js 示例。我們希望您發現這篇文章很有趣,並且現在對 kube-service-bindings 和服務綁定有了更好的理解。
#node #nodejs #mongodb #database #kubernetes
1660710512
В этом кратком руководстве мы расскажем, как шаг за шагом подключить MongoDB к приложению Node.js в Kubernetes.
В предыдущей статье мы настроили доступ между MongoDB Atlas и вашим кластером OpenShift. Если вы успешно выполнили эти шаги, вы готовы развернуть размещенную в облаке базу данных MongoDB в кластере следующим образом:
Рис. 1. Представление «Топология» показывает, что MongoDB Atlas теперь доступен в вашем кластере.
Существует несколько способов развертывания приложения Node.js в OpenShift: через oc
интерфейс командной строки (CLI) OpenShift, odo
CLI, консоль OpenShift и т. д. В этой статье рассматриваются два варианта: консоль OpenShift и Nodeshift , пакет NPM.
С точки зрения разработчика выберите +Добавить→Импортировать из Git .
В поле URL-адрес репозитория Git задайте для URL-адреса репозитория значение https://github.com/nodeshift-blog-examples/kube-service-bindings-examples
. Это репозиторий примеров привязки kube-service-bindings, поддерживаемый нашей командой; он содержит приложение Node.js, которое вы развертываете в этой статье.
Разверните Показать дополнительные параметры Git . В поле Context dir задайте значение src/mongodb
, которое является путем к подкаталогу, в котором находится ваше приложение Node.js.
В образе Builder выберите Node.js и нажмите « Создать » .
Откройте терминал и клонируйте репозиторий git:
git clone https://github.com/nodeshift-blog-examples/kube-service-bindings-examples.git
$ cd ./kube-service-bindings-examples/src/mongodb
Установите Nodeshift глобально:
$ npm install -g nodeshift
Чтобы найти учетные данные для входа в систему, необходимые для следующей команды, которую вы будете использовать, посетите консоль OpenShift. В правом верхнем углу нажмите на свое имя пользователя. Появится раскрывающийся список. Нажмите команду «Копировать логин » (рис. 2), которая перенесет вас на другую страницу. Затем нажмите « Показать токен », чтобы отобразить имя пользователя, пароль и учетные данные сервера для входа в систему с помощью Nodeshift.
Рисунок 2: Под своим именем в консоли вы можете получить учетные данные для входа.
Используя эти учетные данные, теперь вы можете войти в свой кластер OpenShift с помощью Nodeshift:
$ nodeshift login --username=developer --password=password --server=https://api.server
Разверните приложение Node.js с помощью Nodeshift с помощью следующей команды, заменив имя пространства имен на ваше конкретное имя проекта:
$ nodeshift --namespace.name=<selected-project>
Ваше приложение должно быть развернуто и отображаться в представлении «Топология», как показано на рис. 3.
Рис. 3. Приложение Node.js отображается в представлении «Топология».
Последний шаг в этой серии — установить соединение между вашим приложением Node.js и базой данных MongoDB, что мы и сделаем в этом разделе.
На этом этапе в представлении «Топология» должны появиться два экземпляра: приложение Node.js и подключение к вашему экземпляру MongoDB в Atlas (рис. 4).
Рис. 4. В представлении «Топология» показано как приложение Node.js, так и внешняя база данных MongoDB.
Чтобы установить соединение между этими экземплярами, вы будете использовать Service Binding Operator для совместного использования учетных данных и kube-service-bindings для анализа этих учетных данных (данных привязки).
Вы можете создать привязку службы двумя способами:
Мы пойдем по первому варианту, который в нашем случае быстрее и проще.
Наведите указатель мыши на приложение Node.js в представлении «Топология». Должна появиться стрелка. Перетащите стрелку с приложения Node.js на кружок вокруг экземпляра MongoDB. Должна быть видна всплывающая подсказка с надписью « Создать привязку службы» . Отпустите кнопку мыши, и всплывающее окно позволит вам указать имя привязки службы. Щелкните Создать привязку . Контейнер приложения Node.js немедленно перезапустится (рис. 5).
Проверьте среду приложения Node.js, щелкнув контейнер приложения Node.js в представлении «Топология». На правой боковой панели нажмите « Ресурсы» → «Просмотреть журналы» (раздел «Модули») и перейдите на вкладку « Среда ». Переменная SERVICE_BINDING_ROOT
среды должна быть установлена, как показано на рисунке 6.
Последним шагом является чтение данных привязки в каталоге, указанном SERVICE_BINDING_ROOT
переменной, и передача данных клиенту MongoDB для установления соединения с базой данных MongoDB. В вашем приложении Node.js уже есть привязки kube-service-bindings в качестве зависимости. Таким образом, вызов getBinding()
функции, как показано в следующем фрагменте кода JavaScript, выполняет всю тяжелую работу по разбору, очистке и преобразованию данных привязки в формат, пригодный для использования клиентом MongoDB:
const { MongoClient } = require("mongodb");
const serviceBindings = require("kube-service-bindings");
const { url, connectionOptions } = serviceBindings.getBinding("MONGODB", "mongodb");
const mongoClient = new MongoClient(url, connectionOptions);
Вот и все. Посетив URL-адрес приложения Node.js (щелкните значок со стрелкой на узле), вы можете выполнять простые операции CRUD через пользовательский интерфейс в базе данных.
В течение последнего года наша команда активно занималась разработкой привязок kube-service-bindings, что упрощает разработчикам с небольшим или нулевым опытом управления контейнерными приложениями безопасный обмен учетными данными между вспомогательными службами.
В дополнение к работе по разработке kube-service-bindings наша команда предоставляет примеры для большинства клиентов, поддерживаемых kube-service-bindings, инструкции по использованию kube-service-bindings и описание того, как развертывать различные вспомогательные сервисы через Nodeshift в средах Kubernetes и OpenShift.
В этой серии статей показано, какие клиенты поддерживаются и как работают привязки службы и привязки kube-service-bindings. Мы провели вас через весь цикл развертывания службы поддержки приложений Node.js с использованием привязок SBO и kube-service, совместного использования и анализа учетных данных для соединения между приложением Node.js и базой данных MongoDB. kube-service-bindings считывает, анализирует и преобразует данные привязки, спроецированные оператором привязки службы, возвращая данные в форме, которую может напрямую использовать клиент MongoDB.
Чтобы помочь вам использовать привязки kube-service-bindings в других типах развертываний, мы предоставили дополнительные примеры Node.js. Мы надеемся, что вы нашли эту статью интересной и теперь лучше понимаете привязки kube-service-bindings и сервисов в целом.
#узел #nodejs #mongodb #база данных #kubernetes
1660676280
is-reachable
Check if servers are reachable
Works in Node.js and the browser (with a bundler).
The Node.js version will do a TCP handshake with the target's port. It attempts to detect cases where a router redirects the request to itself.
The browser version is limited by the fact that browsers cannot connect to arbitrary ports. It only supports HTTP and HTTPS and the check relies on the /favicon.ico
path being present.
$ npm install is-reachable
const isReachable = require('is-reachable');
(async () => {
console.log(await isReachable('sindresorhus.com'));
//=> true
console.log(await isReachable('google.com:443'));
//=> true
})();
Returns a Promise<boolean>
which is true
if any of the targets
are reachable.
Type: string | string[]
One or more targets to check. Can either be hostname:port
, a URL like https://hostname:port
or even just hostname
. port
must be specified if protocol is not http:
or https:
and defaults to 443
. Protocols other than http:
and https:
are not supported.
Type: object
timeout
Type: number
Default: 5000
Timeout in milliseconds after which a request is considered failed.
Node.js only
Author: Sindresorhus
Source Code: https://github.com/sindresorhus/is-reachable
License: MIT license
1660606680
A library to create readable "multipart/form-data"
streams. Can be used to submit forms and file uploads to other web applications.
The API of this library is inspired by the XMLHttpRequest-2 FormData Interface.
npm install --save form-data
In this example we are constructing a form with 3 fields that contain a string, a buffer and a file stream.
var FormData = require('form-data');
var fs = require('fs');
var form = new FormData();
form.append('my_field', 'my value');
form.append('my_buffer', new Buffer(10));
form.append('my_file', fs.createReadStream('/foo/bar.jpg'));
Also you can use http-response stream:
var FormData = require('form-data');
var http = require('http');
var form = new FormData();
http.request('http://nodejs.org/images/logo.png', function(response) {
form.append('my_field', 'my value');
form.append('my_buffer', new Buffer(10));
form.append('my_logo', response);
});
Or @mikeal's request stream:
var FormData = require('form-data');
var request = require('request');
var form = new FormData();
form.append('my_field', 'my value');
form.append('my_buffer', new Buffer(10));
form.append('my_logo', request('http://nodejs.org/images/logo.png'));
In order to submit this form to a web application, call submit(url, [callback])
method:
form.submit('http://example.org/', function(err, res) {
// res – response object (http.IncomingMessage) //
res.resume();
});
For more advanced request manipulations submit()
method returns http.ClientRequest
object, or you can choose from one of the alternative submission methods.
You can provide custom options, such as maxDataSize
:
var FormData = require('form-data');
var form = new FormData({ maxDataSize: 20971520 });
form.append('my_field', 'my value');
form.append('my_buffer', /* something big */);
List of available options could be found in combined-stream
You can use node's http client interface:
var http = require('http');
var request = http.request({
method: 'post',
host: 'example.org',
path: '/upload',
headers: form.getHeaders()
});
form.pipe(request);
request.on('response', function(res) {
console.log(res.statusCode);
});
Or if you would prefer the 'Content-Length'
header to be set for you:
form.submit('example.org/upload', function(err, res) {
console.log(res.statusCode);
});
To use custom headers and pre-known length in parts:
var CRLF = '\r\n';
var form = new FormData();
var options = {
header: CRLF + '--' + form.getBoundary() + CRLF + 'X-Custom-Header: 123' + CRLF + CRLF,
knownLength: 1
};
form.append('my_buffer', buffer, options);
form.submit('http://example.com/', function(err, res) {
if (err) throw err;
console.log('Done');
});
Form-Data can recognize and fetch all the required information from common types of streams (fs.readStream
, http.response
and mikeal's request
), for some other types of streams you'd need to provide "file"-related information manually:
someModule.stream(function(err, stdout, stderr) {
if (err) throw err;
var form = new FormData();
form.append('file', stdout, {
filename: 'unicycle.jpg', // ... or:
filepath: 'photos/toys/unicycle.jpg',
contentType: 'image/jpeg',
knownLength: 19806
});
form.submit('http://example.com/', function(err, res) {
if (err) throw err;
console.log('Done');
});
});
The filepath
property overrides filename
and may contain a relative path. This is typically used when uploading multiple files from a directory.
For edge cases, like POST request to URL with query string or to pass HTTP auth credentials, object can be passed to form.submit()
as first parameter:
form.submit({
host: 'example.com',
path: '/probably.php?extra=params',
auth: 'username:password'
}, function(err, res) {
console.log(res.statusCode);
});
In case you need to also send custom HTTP headers with the POST request, you can use the headers
key in first parameter of form.submit()
:
form.submit({
host: 'example.com',
path: '/surelynot.php',
headers: {'x-test-header': 'test-header-value'}
}, function(err, res) {
console.log(res.statusCode);
});
Append data to the form. You can submit about any format (string, integer, boolean, buffer, etc.). However, Arrays are not supported and need to be turned into strings by the user.
var form = new FormData();
form.append( 'my_string', 'my value' );
form.append( 'my_integer', 1 );
form.append( 'my_boolean', true );
form.append( 'my_buffer', new Buffer(10) );
form.append( 'my_array_as_json', JSON.stringify( ['bird','cute'] ) )
You may provide a string for options, or an object.
// Set filename by providing a string for options
form.append( 'my_file', fs.createReadStream('/foo/bar.jpg'), 'bar.jpg' );
// provide an object.
form.append( 'my_file', fs.createReadStream('/foo/bar.jpg'), {filename: 'bar.jpg', contentType: 'image/jpeg', knownLength: 19806} );
This method adds the correct content-type
header to the provided array of userHeaders
.
Return the boundary of the formData. By default, the boundary consists of 26 -
followed by 24 numbers for example:
--------------------------515890814546601021194782
Set the boundary string, overriding the default behavior described above.
Note: The boundary must be unique and may not appear in the data.
Return the full formdata request package, as a Buffer. You can insert this Buffer in e.g. Axios to send multipart data.
var form = new FormData();
form.append( 'my_buffer', Buffer.from([0x4a,0x42,0x20,0x52,0x6f,0x63,0x6b,0x73]) );
form.append( 'my_file', fs.readFileSync('/foo/bar.jpg') );
axios.post( 'https://example.com/path/to/api',
form.getBuffer(),
form.getHeaders()
)
Note: Because the output is of type Buffer, you can only append types that are accepted by Buffer: string, Buffer, ArrayBuffer, Array, or Array-like Object. A ReadStream for example will result in an error.
Same as getLength
but synchronous.
Note: getLengthSync doesn't calculate streams length.
Returns the Content-Length
async. The callback is used to handle errors and continue once the length has been calculated
this.getLength(function(err, length) {
if (err) {
this._error(err);
return;
}
// add content length
request.setHeader('Content-Length', length);
...
}.bind(this));
Checks if the length of added values is known.
Submit the form to a web application.
var form = new FormData();
form.append( 'my_string', 'Hello World' );
form.submit( 'http://example.com/', function(err, res) {
// res – response object (http.IncomingMessage) //
res.resume();
} );
Returns the form data as a string. Don't use this if you are sending files or buffers, use getBuffer()
instead.
Form submission using request:
var formData = {
my_field: 'my_value',
my_file: fs.createReadStream(__dirname + '/unicycle.jpg'),
};
request.post({url:'http://service.com/upload', formData: formData}, function(err, httpResponse, body) {
if (err) {
return console.error('upload failed:', err);
}
console.log('Upload successful! Server responded with:', body);
});
For more details see request readme.
You can also submit a form using node-fetch:
var form = new FormData();
form.append('a', 1);
fetch('http://example.com', { method: 'POST', body: form })
.then(function(res) {
return res.json();
}).then(function(json) {
console.log(json);
});
In Node.js you can post a file using axios:
const form = new FormData();
const stream = fs.createReadStream(PATH_TO_FILE);
form.append('image', stream);
// In Node.js environment you need to set boundary in the header field 'Content-Type' by calling method `getHeaders`
const formHeaders = form.getHeaders();
axios.post('http://example.com', form, {
headers: {
...formHeaders,
},
})
.then(response => response)
.catch(error => error)
getLengthSync()
method DOESN'T calculate length for streams, use knownLength
options as workaround.getLength(cb)
will send an error as first parameter of callback if stream length cannot be calculated (e.g. send in custom streams w/o using knownLength
).submit
will not add content-length
if form length is unknown or not calculable.2.x
FormData has dropped support for node@0.10.x
.3.x
FormData has dropped support for node@4.x
.Author: Form-data
Source Code: https://github.com/form-data/form-data
License: MIT license
1660520460
Social Media Application using React with CSS3 & Node.js.
https://social-media-app-6no.pages.dev/
✔️ Authentication with form account
✔️ Authentication with email & password
Design: CSS3 & Styled Components
Authentication: Form auth from scratch
Backend: NodeJs
Libraries:
- redux-logger: console logging redux data flow
- redux: state management
1. Server Setup
#1. clone this project
~ git clone https://github.com/letnagao/social-media-app.git
#2. cd into it
~ cd social-media-app
#3. install server dependencies
~ yarn
#4. start the project
~ yarn start
available scripts
~ yarn run
~ yarn run test
~ yarn run test -o --watch
~ yarn run env
A word of disclaimer, this code is not original! I am simply a student passionate about Front-end and the intersection of code and design, I always try to do courses and projects during my free time, so I must warn you that this code is NOT ORIGINAL.
You can find the source of this code via: https://www.youtube.com/channel/UCVf_ji691VSuKUfmP0RObGA
Pull request are welcome but please open an issue and discuss what you will do before 😊
If you are feeling generous, buy me a coffee! - https://www.buymeacoffee.com/lunagao
Author: letnagao
Source code: https://github.com/letnagao/social-media-app
#react-native #javascript #nodejs #css
1660519800
Send CTRL-C to a Windows console application
Long running stateful processes like servers often hold a lot of system resources that they need to operate. These are things like communication ports, file descriptors, database connections, etc... At some point, when it is time for that process to shut it needs to release all those resources back to the operating system and exit. This process of freeing up all the things that were being used is called "graceful shutdown" and is really important to get right in systems that start and stop processes repeatedly. On Unix systems, the method for achieving a graceful shutdown of a process is to send it a signal (usually either SIGINT
or SIGTERM
).
The process can then register a handler for this signal which releases any resources that it is holding and exits.
The alternative to a graceful shutdown is a "forced termination". This is what happens when a process is unable to respond to a interrupt or termination signal. In this case, the process is ended immediately without the opprotunity to release any of the resources it holds.
On Unix systems, when you invoke process.kill()
on a ChildProcess
object, it sends the SIGTERM
signal. That way, if the process has a SIGTERM
handler it has an opportunity to perform a graceful shutdown.
Windows on the other hand, does not have a method to send signals to a process, so when you invoke the same process.kill()
function on that platform, what you end up with is a forceful termination without any cleanup. However, Windows does have a method for applications to shutdown gracefully, namely hitting CTRL-C
on the console to which the process is attached. And that's what this is all about. In fact, whenever you hit CTRL-C
on a windows console that is running a node
application, node
will translate that CTRL-C
into a SIGINT
and dispatch any SIGINT
handlers that it has registered. Since most well-behaved long-running Nodejs processes respond to SIGINT
, this allows them to shutdown too.
This module exports a single ctrlc
function which accepts a process id, and sends a CTRL-C
event to that console.
Note: This is a no-op on non-windows platforms
import { ctrlc } from 'ctrlc-windows';
export function gracefulShutdown(process) {
if (process.platform === 'win32') {
ctrlc(process.pid);
} else {
process.kill();
}
}
Author: Thefrontside
Source Code: https://github.com/thefrontside/ctrlc-windows
1660418100
OMISOFT BLOG EXAMPLE - FRONT END
Here you can find a simple boilerplate for a Blog based on React.js & Next.js. We use this code in the project SudokuPro.app
To run this app use next commands:
npm run i
npm run dev
Open http://localhost:4000 with your browser to see the result.
This blog consists of three different parts:
OMISOFT BLOG EXAMPLE is released under the MIT license.
See the LICENSE for details.
Author: OmiSoftNet
Source code: https://github.com/OmiSoftNet/omisoft-blog-template-front
License: View license
#react #typescript #javascript #nodejs #nextjs
1660368000
Let's look at how to deploy a Node/Express microservice (along with Postgres) to a Kubernetes cluster on Google Kubernetes Engine (GKE).
Source: https://testdriven.io