Save monolog in mongodb in symfony 4 - mongodb

I want to add monolog in mongodb with default handler(MongoDBHandler) in Symfony 4.
my monolog.yaml file in dev folder
monolog:
handlers:
mongo:
type: mongo
mongo:
id: monolog.logger.mongo
host: '%env(MONGODB_URL)%'
database: '%env(MONGODB_DB)%'
collection: logs
my services.yaml
services:
monolog.logger.mongo:
class: Monolog\Handler\MongoDBHandler
arguments: ['#doctrine_mongodb']
my doctrine_mongodb.yaml
doctrine_mongodb:
auto_generate_proxy_classes: '%kernel.debug%'
auto_generate_hydrator_classes: '%kernel.debug%'
connections:
default:
server: '%env(MONGODB_URL)%'
options:
db: '%env(MONGODB_DB)%'
log:
server: '%env(MONGODB_URL)%'
options:
db: '%env(MONGODB_DB)%'
connect: true
default_database: '%env(MONGODB_DB)%'
document_managers:
log:
auto_mapping: false
logging: false
But doesn't work.
one of the errors:
Cannot autowire service "monolog.logger.mongo": argument "$database"
of method "Monolog\Handler\MongoDBHandler::__construct()" is
type-hinted "string", you should configure its value explicitly.
While i use database option in monolog config.
Is there any document?

Another way to enable mongodb for monolog is:
monolog:
handlers:
mongo:
type: mongo
mongo:
host: '%env(MONGODB_URL)%'
user: myuser
pass: mypass
database: '%env(MONGODB_DB)%'
collection: logs
, So it mean you need to remove id field and add user and pass instead.

If you use doctrine mongodb already, it's possible to re-use it's connection, avoiding more ENV vars to separate the DSN:
monolog:
handlers:
mongo:
type: mongo
mongo:
id: "doctrine_mongodb.odm.default_connection"
database: "%env(MONGODB_DB)%"
collection: MyLogDocument # Keeping this the same, allows you to simply use a doctrine repository to access the documents in your app if needed
level: debug

I get the following error:
Attempted to load class "MongoClient" from the global namespace.
Did you forget a "use" statement?
protected function getMonolog_Handler_MongoService()
{
$this->privates['monolog.handler.mongo'] = $instance = new \Monolog\Handler\MongoDBHandler(new \MongoClient('mongodb://admin:pass#localhost:27017'), 'monolog', 'logs', 100, true);
$instance->pushProcessor(($this->privates['monolog.processor.psr_log_message'] ?? ($this->privates['monolog.processor.psr_log_message'] = new \Monolog\Processor\PsrLogMessageProcessor())));
return $instance;
}

Related

Can a Mongo-Express container connect to MongoDB with TLS?

I have a mongo container, started with the requireTLS TLS mode, and a mongo-express container. Mongo-express does not seem to manage to connect to mongo using TLS.
My docker-compose.yml:
version: '3.1'
services:
mongodb1:
image : "mongo:4.2"
container_name : "mongodb-001"
ports:
- '27017:27017'
environment:
MONGO_INITDB_ROOT_USERNAME : "admin"
MONGO_INITDB_ROOT_PASSWORD : "adminpasswd"
volumes:
- "./mongo-data:/data/db"
- "./etc_mongod.conf:/etc/mongod.conf"
- "./certificates:/etc/certificates:ro"
command:
- "--tlsMode"
- "preferTLS"
- "--tlsDisabledProtocols"
- "none"
- "--tlsCertificateKeyFile"
- "/etc/certificates/certificateKey.pem"
- "--tlsCAFile"
- "/etc/certificates/CA.crt"
- "--tlsAllowConnectionsWithoutCertificates"
mongo-express:
image : "mongo-express:latest"
container_name : "mongo-express-001"
ports:
- '8081:8081'
depends_on:
- mongodb1
volumes:
- "./certificates/CA.crt:/etc/certificates/CA.crt:ro"
environment:
ME_CONFIG_MONGODB_SERVER: "mongodb-001"
ME_CONFIG_MONGODB_PORT: "27017"
ME_CONFIG_MONGODB_ENABLE_ADMIN: "false"
ME_CONFIG_MONGODB_AUTH_DATABASE: "admin"
ME_CONFIG_MONGODB_AUTH_USERNAME: "admin"
ME_CONFIG_MONGODB_AUTH_PASSWORD: "adminpasswd"
ME_CONFIG_MONGODB_ADMINUSERNAME: "admin"
ME_CONFIG_MONGODB_ADMINPASSWORD: "adminpasswd"
ME_CONFIG_SITE_SSL_ENABLED: "true"
ME_CONFIG_MONGODB_CA_FILE: "/etc/certificates/CA.crt"
...and the error message I get:
mongodb-001 | 2020-10-09T14:16:13.299+0000 I NETWORK [listener] connection accepted from 172.31.0.3:44774 #2 (1 connection now open)
mongodb-001 | 2020-10-09T14:16:13.305+0000 I NETWORK [conn2] Error receiving request from client: SSLHandshakeFailed: The server is configured to only allow SSL connections. Ending connection from 172.31.0.3:44774 (connection id: 2)
mongodb-001 | 2020-10-09T14:16:13.305+0000 I NETWORK [conn2] end connection 172.31.0.3:44774 (0 connections now open)
mongo-express-001 |
mongo-express-001 | /node_modules/mongodb/lib/server.js:265
mongo-express-001 | process.nextTick(function() { throw err; })
mongo-express-001 | ^
mongo-express-001 | Error [MongoError]: connection 0 to mongodb-001:27017 closed
mongo-express-001 | at Function.MongoError.create (/node_modules/mongodb-core/lib/error.js:29:11)
mongo-express-001 | at Socket.<anonymous> (/node_modules/mongodb-core/lib/connection/connection.js:200:22)
mongo-express-001 | at Object.onceWrapper (events.js:422:26)
mongo-express-001 | at Socket.emit (events.js:315:20)
mongo-express-001 | at TCP.<anonymous> (net.js:674:12)
mongo-express-001 exited with code 1
Note that:
I can connect to MongoDB using a mongo shell with the same parameters I pass to mongo-express:
mongo "mongodb://admin:adminpasswd#mongodb-001:27017/admin?authSource=admin" --tls --tlsCAFile certificates/CA.crt
If I start MongoDB in preferTLS mode, the mongo-express connection works
tl;dr
Create a new config.js file with the following code
module.exports = {
mongodb: {
connectionOptions: {
ssl: true,
}
}
};
and mount that file in your docker compose file at /node_modules/mongo-express/config.js
Explanation
It appears to be an issue with their config.default.js file. In it, they have this
module.exports = {
mongodb: {
// if a connection string options such as server/port/etc are ignored
connectionString: mongo.connectionString || getConnectionStringFromEnvVariables(),
connectionOptions: {
// ssl: connect to the server using secure SSL
ssl: process.env.ME_CONFIG_MONGODB_SSL || mongo.ssl,
// sslValidate: validate mongod server certificate against CA
sslValidate: process.env.ME_CONFIG_MONGODB_SSLVALIDATE || true,
// sslCA: array of valid CA certificates
sslCA: sslCAFromEnv ? [sslCAFromEnv] : [],
// autoReconnect: automatically reconnect if connection is lost
autoReconnect: true,
// poolSize: size of connection pool (number of connections to use)
poolSize: 4,
}
}
You'll notice the existence of an env var that's not listed (with reason) in their documentation. ME_CONFIG_MONGODB_SSL
This is required to enable tls support. Setting the env var yourself however does nothing but throw an error and break express due to it not being cast to a Boolean. So it just reads as a string 'true' or 'false'.
This code is fixed in their npm package code, but they haven't updated their docker image since late 2021. So the only "fix" I've found for this is to create a new config.js file with the following code
module.exports = {
mongodb: {
connectionOptions: {
ssl: true,
sslValidate: true,
}
}
};
Then mount this file at /node_modules/mongo-express/config.js in your docker-compose file. It'll read these and overwrite the defaults.
Note: I added the sslValidate key:value pair as well due to the fact that it suffers from the same lack of type casting. So if you omit the ME_CONFIG_MONGODB_SSLVALIDATE env var entirely, it'll be set as true, but if you include the env var as either true or false, it'll just simply break (undefined behaviour).

Failed to connect to a mongodb docker container from mongoose on host

I'm trying to connect to mongodb running in docker from the app running on host using mongoose but it failed.
I can't use the port 27017 for the new mongodb container because it is used by other container. So I followed the guide here for setting it up using the compose.
Below are the snippets:
docker-compose.yml
version: '3'
services:
db:
image: mongo:latest
restart: always
ports:
- '8081:8081'
environment:
MONGO_INITDB_ROOT_USERNAME: root1
MONGO_INITDB_ROOT_PASSWORD: password1
But when I do docker-ps, port 27017 still there but I'm not sure if that causes an issue.
PORTS
0.0.0.0:8081->8081/tcp, 27017/tcp
Then I created a new user in admin database.
use admin
db.createUser(
{
user: "admin1",
pwd: "password2",
roles: [ { role: "userAdminAnyDatabase", db: "admin" }, "readWriteAnyDatabase" ]
}
)
server.js
const connectOption = {
useNewUrlParser: true,
user: 'admin1',
pass: 'password2',
authSource: 'admin',
}
const mongoURL = 'mongodb://localhost:8081/app1';
mongoose.connect(mongoURL, connectOption)
.then(() => console.log('MongoDB Connected'))
.catch(error => console.log(error));
And the error I received is
{
MongoNetworkError: failed to connect to server [localhost:8081] on first connect [MongoNetworkError: write EPIPE]
...
...
...
name: 'MongoNetworkError',
errorLabels: [ 'TransientTransactionError' ],
[Symbol(mongoErrorContextSymbol)]: {}
}
Assuming you're running nodejs application as a docker-compose service, in db service remove ports section (including - '8081:8081'
line). In server.js, change const mongoURL = 'mongodb://localhost:8081/app1'; to const mongoURL = 'mongodb://db:27017/app1';.
If you want to access the db from host machine, change ports 8081:8081 to <give-a-port-number>:27017.

Symfony 4 / MongoDB / Docker multiple entries when saving data

I'm using Symfony 4 and MongoDB with docker and i want to save a new document (only one) on my database but multiple entries are inserted.
.env file :
PROJECT_DIR=/var/www/movies
APACHE_PORT=8080
PHP_PORT=9000
MONGODB_USER=test
MONGODB_PASSWORD=test
MONGODB_HOST=mongo
MONGODB_PORT=27017
MONGODB_DB=movies
MONGODB_URL=mongodb://${MONGODB_HOST}:${MONGODB_PORT}
doctrine_mongodb.yaml:
doctrine_mongodb:
auto_generate_proxy_classes: true
auto_generate_hydrator_classes: true
connections:
default:
server: '%env(resolve:MONGODB_URL)%'
options:
username: '%env(resolve:MONGODB_USER)%'
password: '%env(resolve:MONGODB_PASSWORD)%'
default_database: '%env(resolve:MONGODB_DB)%'
document_managers:
default:
auto_mapping: true
mappings:
App:
is_bundle: false
type: annotation
dir: '%kernel.project_dir%/src/Document'
prefix: 'App\Document'
alias: App
Controller index function:
/**
* #Route("/", name="base")
*/
public function index(DocumentManager $dm)
{
$movie = new Movie();
$movie->setTitle("Test");
$dm->persist($movie);
$dm->flush();
return $this->render('base/index.html.twig');
}
Finally, i resolved the problem.
I commented the following line that was hanging on my base.html.twig, which was calling again the localhost.
{# <link rel='stylesheet' id='quick-preset-css' href='{{ asset('') }}' type='text/css' media='all' />#}

codeception call to a member function connection() on null

I'm trying to set up codeception to use a sqlite database during testing but i am running into the error bellow. I've tried to include bootstrap/app.php so that the application is running but that didn't fix it. Does anybody have an idea?
I'm using:
lumen v5.7.4
php v7.2.10
codeception v2.5.1
LPaymentTransactionTest.php
public function testReturn(): void
{
\App\DAO\Order::find(1);
}
codeception.yml
paths:
tests: tests
output: tests/_output
data: tests/_data
support: tests/_support
envs: tests/_envs
actor_suffix: Tester
extensions:
enabled:
- Codeception\Extension\RunFailed
modules:
enabled:
- Asserts
- \Helper\Unit
- Db:
dsn: 'sqlite:tests/_data/sqliteTestDb.db'
user: ''
password: ''
# dump: 'tests/_data/test.sql'
dump: 'tests/_data/databaseDump.sql'
populate: true
cleanup: true
full error
Call to a member function connection() on null
/home/projects/vendor/illuminate/database/Eloquent/Model.php:1239
/home/projects/vendor/illuminate/database/Eloquent/Model.php:1205
/home/projects/vendor/illuminate/database/Eloquent/Model.php:1035
/home/projects/vendor/illuminate/database/Eloquent/Model.php:952
/home/projects/vendor/illuminate/database/Eloquent/Model.php:988
/home/projects/vendor/illuminate/database/Eloquent/Model.php:941
/home/projects/vendor/illuminate/database/Eloquent/Model.php:1608
/home/projects/vendor/illuminate/database/Eloquent/Model.php:1620
/home/projects/tests/unit/LPaymentTransactionTest.php:96
/tmp/ide-codeception.php:40
edit:
the model does work outside of the tests. so if i call the model through in routes/web.php it returns the data without a problem.
it just doesn't seem to function within the test
edit2:
looks like the application isn't being launched, will update with fix once i find it
actor: UnitTester
modules:
enabled:
- Asserts
- \Helper\Unit
- Cli
- Lumen
- Db:
dsn: 'sqlite:tests/_data/database.sqlite'
dbname: 'tests/_data/database.sqlite'
dump: 'tests/_data/test.sql'
user: ''
password: ''
populate: true
cleanup: false
reconnect: true
waitlock: 0
step_decorators: ~

MongoDB with Geddy

I'd like to use MongoDB with Geddy. I've edited my "production.js" file but it seems not working... I don't remember my MondoDB username and password...
I get this error : Error: 500 Internal Server Error
production.js :
var config = {
detailedErrors: false
, hostname: null
, port: 4000
, model: {
defaultAdapter: 'mongo'
}
, db: {
mongo: {
username: 'root'
, dbname: 'anthonycluse'
, prefix: null
, password: 'root'
, host: 'localhost'
, port: 27017
}
}
};
module.exports = config;
UPDATE
Command :
geddy gen secret
config.js :
var config = {
detailedErrors: true
, debug: true
, hostname: null
, port: 4000
, model: {
defaultAdapter: 'mongo'
}
, db: {
mongo: {
dbname: 'anthonycluse'
, host: 'localhost'
, port: 27017
}
}
A few things could be going wrong here.
Try turning on detailed errors detailedErrors: true so that you can see what's going wrong in the console.
Also, it seems unlikely that your password and username would both be "root" in production. Are you running Geddy in development? In that case, you should be editing development.js.
You can see in the console output what mode (development or production) you have started geddy in.